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
@@ -62,6 +62,11 @@ SPIRAM_SPEEDS = {
62
62
  }
63
63
 
64
64
 
65
+ def supported() -> bool:
66
+ variant = get_esp32_variant()
67
+ return variant in SPIRAM_MODES
68
+
69
+
65
70
  def validate_psram_mode(config):
66
71
  esp32_config = fv.full_config.get()[PLATFORM_ESP32]
67
72
  if config[CONF_SPEED] == "120MHZ":
@@ -95,7 +100,7 @@ def get_config_schema(config):
95
100
  variant = get_esp32_variant()
96
101
  speeds = [f"{s}MHZ" for s in SPIRAM_SPEEDS.get(variant, [])]
97
102
  if not speeds:
98
- return cv.Invalid("PSRAM is not supported on this chip")
103
+ raise cv.Invalid("PSRAM is not supported on this chip")
99
104
  modes = SPIRAM_MODES[variant]
100
105
  return cv.Schema(
101
106
  {
@@ -121,33 +126,30 @@ async def to_code(config):
121
126
  if config[CONF_MODE] == TYPE_OCTAL:
122
127
  cg.add_platformio_option("board_build.arduino.memory_type", "qio_opi")
123
128
 
124
- if CORE.using_esp_idf:
125
- add_idf_sdkconfig_option(
126
- f"CONFIG_{get_esp32_variant().upper()}_SPIRAM_SUPPORT", True
127
- )
128
- add_idf_sdkconfig_option("CONFIG_SOC_SPIRAM_SUPPORTED", True)
129
- add_idf_sdkconfig_option("CONFIG_SPIRAM", True)
130
- add_idf_sdkconfig_option("CONFIG_SPIRAM_USE", True)
131
- add_idf_sdkconfig_option("CONFIG_SPIRAM_USE_CAPS_ALLOC", True)
132
- add_idf_sdkconfig_option("CONFIG_SPIRAM_IGNORE_NOTFOUND", True)
133
-
134
- add_idf_sdkconfig_option(
135
- f"CONFIG_SPIRAM_MODE_{SDK_MODES[config[CONF_MODE]]}", True
136
- )
137
-
138
- # Remove MHz suffix, convert to int
139
- speed = int(config[CONF_SPEED][:-3])
140
- add_idf_sdkconfig_option(f"CONFIG_SPIRAM_SPEED_{speed}M", True)
141
- add_idf_sdkconfig_option("CONFIG_SPIRAM_SPEED", speed)
142
- if config[CONF_MODE] == TYPE_OCTAL and speed == 120:
143
- add_idf_sdkconfig_option("CONFIG_ESPTOOLPY_FLASHFREQ_120M", True)
144
- add_idf_sdkconfig_option("CONFIG_BOOTLOADER_FLASH_DC_AWARE", True)
145
- if CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION] >= cv.Version(5, 4, 0):
146
- add_idf_sdkconfig_option(
147
- "CONFIG_SPIRAM_TIMING_TUNING_POINT_VIA_TEMPERATURE_SENSOR", True
148
- )
149
- if config[CONF_ENABLE_ECC]:
150
- add_idf_sdkconfig_option("CONFIG_SPIRAM_ECC_ENABLE", True)
129
+ add_idf_sdkconfig_option(
130
+ f"CONFIG_{get_esp32_variant().upper()}_SPIRAM_SUPPORT", True
131
+ )
132
+ add_idf_sdkconfig_option("CONFIG_SOC_SPIRAM_SUPPORTED", True)
133
+ add_idf_sdkconfig_option("CONFIG_SPIRAM", True)
134
+ add_idf_sdkconfig_option("CONFIG_SPIRAM_USE", True)
135
+ add_idf_sdkconfig_option("CONFIG_SPIRAM_USE_CAPS_ALLOC", True)
136
+ add_idf_sdkconfig_option("CONFIG_SPIRAM_IGNORE_NOTFOUND", True)
137
+
138
+ add_idf_sdkconfig_option(f"CONFIG_SPIRAM_MODE_{SDK_MODES[config[CONF_MODE]]}", True)
139
+
140
+ # Remove MHz suffix, convert to int
141
+ speed = int(config[CONF_SPEED][:-3])
142
+ add_idf_sdkconfig_option(f"CONFIG_SPIRAM_SPEED_{speed}M", True)
143
+ add_idf_sdkconfig_option("CONFIG_SPIRAM_SPEED", speed)
144
+ if config[CONF_MODE] == TYPE_OCTAL and speed == 120:
145
+ add_idf_sdkconfig_option("CONFIG_ESPTOOLPY_FLASHFREQ_120M", True)
146
+ add_idf_sdkconfig_option("CONFIG_BOOTLOADER_FLASH_DC_AWARE", True)
147
+ if CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION] >= cv.Version(5, 4, 0):
148
+ add_idf_sdkconfig_option(
149
+ "CONFIG_SPIRAM_TIMING_TUNING_POINT_VIA_TEMPERATURE_SENSOR", True
150
+ )
151
+ if config[CONF_ENABLE_ECC]:
152
+ add_idf_sdkconfig_option("CONFIG_SPIRAM_ECC_ENABLE", True)
151
153
 
152
154
  cg.add_define("USE_PSRAM")
153
155
 
@@ -8,6 +8,7 @@ namespace esphome {
8
8
  namespace qmc5883l {
9
9
 
10
10
  static const char *const TAG = "qmc5883l";
11
+
11
12
  static const uint8_t QMC5883L_ADDRESS = 0x0D;
12
13
 
13
14
  static const uint8_t QMC5883L_REGISTER_DATA_X_LSB = 0x00;
@@ -32,6 +33,10 @@ void QMC5883LComponent::setup() {
32
33
  }
33
34
  delay(10);
34
35
 
36
+ if (this->drdy_pin_) {
37
+ this->drdy_pin_->setup();
38
+ }
39
+
35
40
  uint8_t control_1 = 0;
36
41
  control_1 |= 0b01 << 0; // MODE (Mode) -> 0b00=standby, 0b01=continuous
37
42
  control_1 |= this->datarate_ << 2;
@@ -64,6 +69,7 @@ void QMC5883LComponent::setup() {
64
69
  high_freq_.start();
65
70
  }
66
71
  }
72
+
67
73
  void QMC5883LComponent::dump_config() {
68
74
  ESP_LOGCONFIG(TAG, "QMC5883L:");
69
75
  LOG_I2C_DEVICE(this);
@@ -77,11 +83,20 @@ void QMC5883LComponent::dump_config() {
77
83
  LOG_SENSOR(" ", "Z Axis", this->z_sensor_);
78
84
  LOG_SENSOR(" ", "Heading", this->heading_sensor_);
79
85
  LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
86
+ LOG_PIN(" DRDY Pin: ", this->drdy_pin_);
80
87
  }
88
+
81
89
  float QMC5883LComponent::get_setup_priority() const { return setup_priority::DATA; }
90
+
82
91
  void QMC5883LComponent::update() {
83
92
  i2c::ErrorCode err;
84
93
  uint8_t status = false;
94
+
95
+ // If DRDY pin is configured and the data is not ready return.
96
+ if (this->drdy_pin_ && !this->drdy_pin_->digital_read()) {
97
+ return;
98
+ }
99
+
85
100
  // Status byte gets cleared when data is read, so we have to read this first.
86
101
  // If status and two axes are desired, it's possible to save one byte of traffic by enabling
87
102
  // ROL_PNT in setup and reading 7 bytes starting at the status register.
@@ -3,6 +3,7 @@
3
3
  #include "esphome/core/component.h"
4
4
  #include "esphome/components/sensor/sensor.h"
5
5
  #include "esphome/components/i2c/i2c.h"
6
+ #include "esphome/core/hal.h"
6
7
 
7
8
  namespace esphome {
8
9
  namespace qmc5883l {
@@ -33,6 +34,7 @@ class QMC5883LComponent : public PollingComponent, public i2c::I2CDevice {
33
34
  float get_setup_priority() const override;
34
35
  void update() override;
35
36
 
37
+ void set_drdy_pin(GPIOPin *pin) { drdy_pin_ = pin; }
36
38
  void set_datarate(QMC5883LDatarate datarate) { datarate_ = datarate; }
37
39
  void set_range(QMC5883LRange range) { range_ = range; }
38
40
  void set_oversampling(QMC5883LOversampling oversampling) { oversampling_ = oversampling; }
@@ -51,6 +53,7 @@ class QMC5883LComponent : public PollingComponent, public i2c::I2CDevice {
51
53
  sensor::Sensor *z_sensor_{nullptr};
52
54
  sensor::Sensor *heading_sensor_{nullptr};
53
55
  sensor::Sensor *temperature_sensor_{nullptr};
56
+ GPIOPin *drdy_pin_{nullptr};
54
57
  enum ErrorCode {
55
58
  NONE = 0,
56
59
  COMMUNICATION_FAILED,
@@ -1,8 +1,12 @@
1
+ import logging
2
+
3
+ from esphome import pins
1
4
  import esphome.codegen as cg
2
5
  from esphome.components import i2c, sensor
3
6
  import esphome.config_validation as cv
4
7
  from esphome.const import (
5
8
  CONF_ADDRESS,
9
+ CONF_DATA_RATE,
6
10
  CONF_FIELD_STRENGTH_X,
7
11
  CONF_FIELD_STRENGTH_Y,
8
12
  CONF_FIELD_STRENGTH_Z,
@@ -21,6 +25,10 @@ from esphome.const import (
21
25
  UNIT_MICROTESLA,
22
26
  )
23
27
 
28
+ _LOGGER = logging.getLogger(__name__)
29
+
30
+ CONF_DRDY_PIN = "drdy_pin"
31
+
24
32
  DEPENDENCIES = ["i2c"]
25
33
 
26
34
  qmc5883l_ns = cg.esphome_ns.namespace("qmc5883l")
@@ -52,6 +60,18 @@ QMC5883LOversamplings = {
52
60
  }
53
61
 
54
62
 
63
+ def validate_config(config):
64
+ if (
65
+ config[CONF_UPDATE_INTERVAL].total_milliseconds < 15
66
+ and CONF_DRDY_PIN not in config
67
+ ):
68
+ _LOGGER.warning(
69
+ "[qmc5883l] 'update_interval' is less than 15ms and 'drdy_pin' is "
70
+ "not configured, this may result in I2C errors"
71
+ )
72
+ return config
73
+
74
+
55
75
  def validate_enum(enum_values, units=None, int=True):
56
76
  _units = []
57
77
  if units is not None:
@@ -88,7 +108,7 @@ temperature_schema = sensor.sensor_schema(
88
108
  state_class=STATE_CLASS_MEASUREMENT,
89
109
  )
90
110
 
91
- CONFIG_SCHEMA = (
111
+ CONFIG_SCHEMA = cv.All(
92
112
  cv.Schema(
93
113
  {
94
114
  cv.GenerateID(): cv.declare_id(QMC5883LComponent),
@@ -104,29 +124,25 @@ CONFIG_SCHEMA = (
104
124
  cv.Optional(CONF_FIELD_STRENGTH_Z): field_strength_schema,
105
125
  cv.Optional(CONF_HEADING): heading_schema,
106
126
  cv.Optional(CONF_TEMPERATURE): temperature_schema,
127
+ cv.Optional(CONF_DRDY_PIN): pins.gpio_input_pin_schema,
128
+ cv.Optional(CONF_DATA_RATE, default="200hz"): validate_enum(
129
+ QMC5883LDatarates, units=["hz", "Hz"]
130
+ ),
107
131
  }
108
132
  )
109
133
  .extend(cv.polling_component_schema("60s"))
110
- .extend(i2c.i2c_device_schema(0x0D))
134
+ .extend(i2c.i2c_device_schema(0x0D)),
135
+ validate_config,
111
136
  )
112
137
 
113
138
 
114
- def auto_data_rate(config):
115
- interval_sec = config[CONF_UPDATE_INTERVAL].total_milliseconds / 1000
116
- interval_hz = 1.0 / interval_sec
117
- for datarate in sorted(QMC5883LDatarates.keys()):
118
- if float(datarate) >= interval_hz:
119
- return QMC5883LDatarates[datarate]
120
- return QMC5883LDatarates[200]
121
-
122
-
123
139
  async def to_code(config):
124
140
  var = cg.new_Pvariable(config[CONF_ID])
125
141
  await cg.register_component(var, config)
126
142
  await i2c.register_i2c_device(var, config)
127
143
 
128
144
  cg.add(var.set_oversampling(config[CONF_OVERSAMPLING]))
129
- cg.add(var.set_datarate(auto_data_rate(config)))
145
+ cg.add(var.set_datarate(config[CONF_DATA_RATE]))
130
146
  cg.add(var.set_range(config[CONF_RANGE]))
131
147
  if CONF_FIELD_STRENGTH_X in config:
132
148
  sens = await sensor.new_sensor(config[CONF_FIELD_STRENGTH_X])
@@ -143,3 +159,6 @@ async def to_code(config):
143
159
  if CONF_TEMPERATURE in config:
144
160
  sens = await sensor.new_sensor(config[CONF_TEMPERATURE])
145
161
  cg.add(var.set_temperature_sensor(sens))
162
+ if CONF_DRDY_PIN in config:
163
+ pin = await cg.gpio_pin_expression(config[CONF_DRDY_PIN])
164
+ cg.add(var.set_drdy_pin(pin))
@@ -10,8 +10,8 @@ constexpr uint32_t BIT_MARK_US = 580; // 70us seems like a safe time delta for
10
10
  constexpr uint32_t BIT_ONE_SPACE_US = 1640;
11
11
  constexpr uint32_t BIT_ZERO_SPACE_US = 545;
12
12
  constexpr uint64_t HEADER = 0b011001001100010uL; // 15 bits
13
- constexpr uint64_t HEADER_SIZE = 15;
14
- constexpr uint64_t CODE_SIZE = 17;
13
+ constexpr size_t HEADER_SIZE = 15;
14
+ constexpr size_t CODE_SIZE = 17;
15
15
 
16
16
  void GoboxProtocol::dump_timings_(const RawTimings &timings) const {
17
17
  ESP_LOGD(TAG, "Gobox: size=%u", timings.size());
@@ -39,7 +39,7 @@ void GoboxProtocol::encode(RemoteTransmitData *dst, const GoboxData &data) {
39
39
  }
40
40
 
41
41
  optional<GoboxData> GoboxProtocol::decode(RemoteReceiveData src) {
42
- if (src.size() < ((HEADER_SIZE + CODE_SIZE) * 2 + 1)) {
42
+ if (static_cast<size_t>(src.size()) < ((HEADER_SIZE + CODE_SIZE) * 2 + 1)) {
43
43
  return {};
44
44
  }
45
45
 
@@ -5,6 +5,8 @@ from esphome.config_helpers import filter_source_files_from_platform
5
5
  import esphome.config_validation as cv
6
6
  from esphome.const import (
7
7
  CONF_BUFFER_SIZE,
8
+ CONF_CARRIER_DUTY_PERCENT,
9
+ CONF_CARRIER_FREQUENCY,
8
10
  CONF_CLOCK_RESOLUTION,
9
11
  CONF_DUMP,
10
12
  CONF_FILTER,
@@ -149,6 +151,14 @@ CONFIG_SCHEMA = remote_base.validate_triggers(
149
151
  ),
150
152
  cv.boolean,
151
153
  ),
154
+ cv.SplitDefault(CONF_CARRIER_DUTY_PERCENT, esp32=100): cv.All(
155
+ cv.only_on_esp32,
156
+ cv.percentage_int,
157
+ cv.Range(min=1, max=100),
158
+ ),
159
+ cv.SplitDefault(CONF_CARRIER_FREQUENCY, esp32="0Hz"): cv.All(
160
+ cv.only_on_esp32, cv.frequency, cv.int_
161
+ ),
152
162
  }
153
163
  )
154
164
  .extend(cv.COMPONENT_SCHEMA)
@@ -168,6 +178,8 @@ async def to_code(config):
168
178
  cg.add(var.set_clock_resolution(config[CONF_CLOCK_RESOLUTION]))
169
179
  if CONF_FILTER_SYMBOLS in config:
170
180
  cg.add(var.set_filter_symbols(config[CONF_FILTER_SYMBOLS]))
181
+ cg.add(var.set_carrier_duty_percent(config[CONF_CARRIER_DUTY_PERCENT]))
182
+ cg.add(var.set_carrier_frequency(config[CONF_CARRIER_FREQUENCY]))
171
183
  else:
172
184
  var = cg.new_Pvariable(config[CONF_ID], pin)
173
185
 
@@ -196,8 +208,8 @@ FILTER_SOURCE_FILES = filter_source_files_from_platform(
196
208
  PlatformFramework.ESP32_ARDUINO,
197
209
  PlatformFramework.ESP32_IDF,
198
210
  },
199
- "remote_receiver_esp8266.cpp": {PlatformFramework.ESP8266_ARDUINO},
200
- "remote_receiver_libretiny.cpp": {
211
+ "remote_receiver.cpp": {
212
+ PlatformFramework.ESP8266_ARDUINO,
201
213
  PlatformFramework.BK72XX_ARDUINO,
202
214
  PlatformFramework.RTL87XX_ARDUINO,
203
215
  PlatformFramework.LN882X_ARDUINO,
@@ -3,12 +3,12 @@
3
3
  #include "esphome/core/helpers.h"
4
4
  #include "esphome/core/log.h"
5
5
 
6
- #ifdef USE_ESP8266
6
+ #if defined(USE_LIBRETINY) || defined(USE_ESP8266)
7
7
 
8
8
  namespace esphome {
9
9
  namespace remote_receiver {
10
10
 
11
- static const char *const TAG = "remote_receiver.esp8266";
11
+ static const char *const TAG = "remote_receiver";
12
12
 
13
13
  void IRAM_ATTR HOT RemoteReceiverComponentStore::gpio_intr(RemoteReceiverComponentStore *arg) {
14
14
  const uint32_t now = micros();
@@ -64,6 +64,8 @@ class RemoteReceiverComponent : public remote_base::RemoteReceiverBase,
64
64
  void set_filter_symbols(uint32_t filter_symbols) { this->filter_symbols_ = filter_symbols; }
65
65
  void set_receive_symbols(uint32_t receive_symbols) { this->receive_symbols_ = receive_symbols; }
66
66
  void set_with_dma(bool with_dma) { this->with_dma_ = with_dma; }
67
+ void set_carrier_duty_percent(uint8_t carrier_duty_percent) { this->carrier_duty_percent_ = carrier_duty_percent; }
68
+ void set_carrier_frequency(uint32_t carrier_frequency) { this->carrier_frequency_ = carrier_frequency; }
67
69
  #endif
68
70
  void set_buffer_size(uint32_t buffer_size) { this->buffer_size_ = buffer_size; }
69
71
  void set_filter_us(uint32_t filter_us) { this->filter_us_ = filter_us; }
@@ -76,6 +78,8 @@ class RemoteReceiverComponent : public remote_base::RemoteReceiverBase,
76
78
  uint32_t filter_symbols_{0};
77
79
  uint32_t receive_symbols_{0};
78
80
  bool with_dma_{false};
81
+ uint32_t carrier_frequency_{0};
82
+ uint8_t carrier_duty_percent_{100};
79
83
  esp_err_t error_code_{ESP_OK};
80
84
  std::string error_string_{""};
81
85
  #endif
@@ -72,6 +72,21 @@ void RemoteReceiverComponent::setup() {
72
72
  return;
73
73
  }
74
74
 
75
+ if (this->carrier_frequency_ > 0 && 0 < this->carrier_duty_percent_ && this->carrier_duty_percent_ < 100) {
76
+ rmt_carrier_config_t carrier;
77
+ memset(&carrier, 0, sizeof(carrier));
78
+ carrier.frequency_hz = this->carrier_frequency_;
79
+ carrier.duty_cycle = (float) this->carrier_duty_percent_ / 100.0f;
80
+ carrier.flags.polarity_active_low = this->pin_->is_inverted();
81
+ error = rmt_apply_carrier(this->channel_, &carrier);
82
+ if (error != ESP_OK) {
83
+ this->error_code_ = error;
84
+ this->error_string_ = "in rmt_apply_carrier";
85
+ this->mark_failed();
86
+ return;
87
+ }
88
+ }
89
+
75
90
  rmt_rx_event_callbacks_t callbacks;
76
91
  memset(&callbacks, 0, sizeof(callbacks));
77
92
  callbacks.on_recv_done = rmt_callback;
@@ -111,11 +126,13 @@ void RemoteReceiverComponent::dump_config() {
111
126
  " Filter symbols: %" PRIu32 "\n"
112
127
  " Receive symbols: %" PRIu32 "\n"
113
128
  " Tolerance: %" PRIu32 "%s\n"
129
+ " Carrier frequency: %" PRIu32 " hz\n"
130
+ " Carrier duty: %u%%\n"
114
131
  " Filter out pulses shorter than: %" PRIu32 " us\n"
115
132
  " Signal is done after %" PRIu32 " us of no changes",
116
133
  this->clock_resolution_, this->rmt_symbols_, this->filter_symbols_, this->receive_symbols_,
117
134
  this->tolerance_, (this->tolerance_mode_ == remote_base::TOLERANCE_MODE_TIME) ? " us" : "%",
118
- this->filter_us_, this->idle_us_);
135
+ this->carrier_frequency_, this->carrier_duty_percent_, this->filter_us_, this->idle_us_);
119
136
  if (this->is_failed()) {
120
137
  ESP_LOGE(TAG, "Configuring RMT driver failed: %s (%s)", esp_err_to_name(this->error_code_),
121
138
  this->error_string_.c_str());
@@ -131,8 +131,8 @@ FILTER_SOURCE_FILES = filter_source_files_from_platform(
131
131
  PlatformFramework.ESP32_ARDUINO,
132
132
  PlatformFramework.ESP32_IDF,
133
133
  },
134
- "remote_transmitter_esp8266.cpp": {PlatformFramework.ESP8266_ARDUINO},
135
- "remote_transmitter_libretiny.cpp": {
134
+ "remote_transmitter.cpp": {
135
+ PlatformFramework.ESP8266_ARDUINO,
136
136
  PlatformFramework.BK72XX_ARDUINO,
137
137
  PlatformFramework.RTL87XX_ARDUINO,
138
138
  PlatformFramework.LN882X_ARDUINO,
@@ -2,10 +2,113 @@
2
2
  #include "esphome/core/log.h"
3
3
  #include "esphome/core/application.h"
4
4
 
5
+ #if defined(USE_LIBRETINY) || defined(USE_ESP8266)
6
+
5
7
  namespace esphome {
6
8
  namespace remote_transmitter {
7
9
 
8
10
  static const char *const TAG = "remote_transmitter";
9
11
 
12
+ void RemoteTransmitterComponent::setup() {
13
+ this->pin_->setup();
14
+ this->pin_->digital_write(false);
15
+ }
16
+
17
+ void RemoteTransmitterComponent::dump_config() {
18
+ ESP_LOGCONFIG(TAG,
19
+ "Remote Transmitter:\n"
20
+ " Carrier Duty: %u%%",
21
+ this->carrier_duty_percent_);
22
+ LOG_PIN(" Pin: ", this->pin_);
23
+ }
24
+
25
+ void RemoteTransmitterComponent::calculate_on_off_time_(uint32_t carrier_frequency, uint32_t *on_time_period,
26
+ uint32_t *off_time_period) {
27
+ if (carrier_frequency == 0) {
28
+ *on_time_period = 0;
29
+ *off_time_period = 0;
30
+ return;
31
+ }
32
+ uint32_t period = (1000000UL + carrier_frequency / 2) / carrier_frequency; // round(1000000/freq)
33
+ period = std::max(uint32_t(1), period);
34
+ *on_time_period = (period * this->carrier_duty_percent_) / 100;
35
+ *off_time_period = period - *on_time_period;
36
+ }
37
+
38
+ void RemoteTransmitterComponent::await_target_time_() {
39
+ const uint32_t current_time = micros();
40
+ if (this->target_time_ == 0) {
41
+ this->target_time_ = current_time;
42
+ } else if ((int32_t) (this->target_time_ - current_time) > 0) {
43
+ #if defined(USE_LIBRETINY)
44
+ // busy loop for libretiny is required (see the comment inside micros() in wiring.c)
45
+ while ((int32_t) (this->target_time_ - micros()) > 0)
46
+ ;
47
+ #else
48
+ delayMicroseconds(this->target_time_ - current_time);
49
+ #endif
50
+ }
51
+ }
52
+
53
+ void RemoteTransmitterComponent::mark_(uint32_t on_time, uint32_t off_time, uint32_t usec) {
54
+ this->await_target_time_();
55
+ this->pin_->digital_write(true);
56
+
57
+ const uint32_t target = this->target_time_ + usec;
58
+ if (this->carrier_duty_percent_ < 100 && (on_time > 0 || off_time > 0)) {
59
+ while (true) { // Modulate with carrier frequency
60
+ this->target_time_ += on_time;
61
+ if ((int32_t) (this->target_time_ - target) >= 0)
62
+ break;
63
+ this->await_target_time_();
64
+ this->pin_->digital_write(false);
65
+
66
+ this->target_time_ += off_time;
67
+ if ((int32_t) (this->target_time_ - target) >= 0)
68
+ break;
69
+ this->await_target_time_();
70
+ this->pin_->digital_write(true);
71
+ }
72
+ }
73
+ this->target_time_ = target;
74
+ }
75
+
76
+ void RemoteTransmitterComponent::space_(uint32_t usec) {
77
+ this->await_target_time_();
78
+ this->pin_->digital_write(false);
79
+ this->target_time_ += usec;
80
+ }
81
+
82
+ void RemoteTransmitterComponent::digital_write(bool value) { this->pin_->digital_write(value); }
83
+
84
+ void RemoteTransmitterComponent::send_internal(uint32_t send_times, uint32_t send_wait) {
85
+ ESP_LOGD(TAG, "Sending remote code");
86
+ uint32_t on_time, off_time;
87
+ this->calculate_on_off_time_(this->temp_.get_carrier_frequency(), &on_time, &off_time);
88
+ this->target_time_ = 0;
89
+ this->transmit_trigger_->trigger();
90
+ for (uint32_t i = 0; i < send_times; i++) {
91
+ InterruptLock lock;
92
+ for (int32_t item : this->temp_.get_data()) {
93
+ if (item > 0) {
94
+ const auto length = uint32_t(item);
95
+ this->mark_(on_time, off_time, length);
96
+ } else {
97
+ const auto length = uint32_t(-item);
98
+ this->space_(length);
99
+ }
100
+ App.feed_wdt();
101
+ }
102
+ this->await_target_time_(); // wait for duration of last pulse
103
+ this->pin_->digital_write(false);
104
+
105
+ if (i + 1 < send_times)
106
+ this->target_time_ += send_wait;
107
+ }
108
+ this->complete_trigger_->trigger();
109
+ }
110
+
10
111
  } // namespace remote_transmitter
11
112
  } // namespace esphome
113
+
114
+ #endif
@@ -1,5 +1,5 @@
1
1
  import logging
2
- import os
2
+ from pathlib import Path
3
3
  from string import ascii_letters, digits
4
4
 
5
5
  import esphome.codegen as cg
@@ -19,7 +19,7 @@ from esphome.const import (
19
19
  ThreadModel,
20
20
  )
21
21
  from esphome.core import CORE, CoroPriority, EsphomeError, coroutine_with_priority
22
- from esphome.helpers import copy_file_if_changed, mkdir_p, read_file, write_file
22
+ from esphome.helpers import copy_file_if_changed, read_file, write_file_if_changed
23
23
 
24
24
  from .const import KEY_BOARD, KEY_PIO_FILES, KEY_RP2040, rp2040_ns
25
25
 
@@ -221,18 +221,18 @@ def generate_pio_files() -> bool:
221
221
  if not files:
222
222
  return False
223
223
  for key, data in files.items():
224
- pio_path = CORE.relative_build_path(f"src/pio/{key}.pio")
225
- mkdir_p(os.path.dirname(pio_path))
226
- write_file(pio_path, data)
224
+ pio_path = CORE.build_path / "src" / "pio" / f"{key}.pio"
225
+ pio_path.parent.mkdir(parents=True, exist_ok=True)
226
+ write_file_if_changed(pio_path, data)
227
227
  includes.append(f"pio/{key}.pio.h")
228
228
 
229
- write_file(
229
+ write_file_if_changed(
230
230
  CORE.relative_build_path("src/pio_includes.h"),
231
231
  "#pragma once\n" + "\n".join([f'#include "{include}"' for include in includes]),
232
232
  )
233
233
 
234
- dir = os.path.dirname(__file__)
235
- build_pio_file = os.path.join(dir, "build_pio.py.script")
234
+ dir = Path(__file__).parent
235
+ build_pio_file = dir / "build_pio.py.script"
236
236
  copy_file_if_changed(
237
237
  build_pio_file,
238
238
  CORE.relative_build_path("build_pio.py"),
@@ -243,8 +243,8 @@ def generate_pio_files() -> bool:
243
243
 
244
244
  # Called by writer.py
245
245
  def copy_files():
246
- dir = os.path.dirname(__file__)
247
- post_build_file = os.path.join(dir, "post_build.py.script")
246
+ dir = Path(__file__).parent
247
+ post_build_file = dir / "post_build.py.script"
248
248
  copy_file_if_changed(
249
249
  post_build_file,
250
250
  CORE.relative_build_path("post_build.py"),
@@ -252,4 +252,4 @@ def copy_files():
252
252
  if generate_pio_files():
253
253
  path = CORE.relative_src_path("esphome.h")
254
254
  content = read_file(path).rstrip("\n")
255
- write_file(path, content + '\n#include "pio_includes.h"\n')
255
+ write_file_if_changed(path, content + '\n#include "pio_includes.h"\n')
@@ -215,7 +215,7 @@ void Rtttl::loop() {
215
215
  sample[x].right = 0;
216
216
  }
217
217
 
218
- if (x >= SAMPLE_BUFFER_SIZE || this->samples_sent_ >= this->samples_count_) {
218
+ if (static_cast<size_t>(x) >= SAMPLE_BUFFER_SIZE || this->samples_sent_ >= this->samples_count_) {
219
219
  break;
220
220
  }
221
221
  this->samples_sent_++;
@@ -374,7 +374,7 @@ void Rtttl::loop() {
374
374
  this->last_note_ = millis();
375
375
  }
376
376
 
377
- #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_DEBUG
377
+ #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
378
378
  static const LogString *state_to_string(State state) {
379
379
  switch (state) {
380
380
  case STATE_STOPPED:
@@ -66,7 +66,7 @@ CONFIG_SCHEMA = (
66
66
  ),
67
67
  cv.Optional(CONF_AMBIENT_PRESSURE_COMPENSATION, default=0): cv.pressure,
68
68
  cv.Optional(CONF_TEMPERATURE_OFFSET): cv.All(
69
- cv.temperature,
69
+ cv.temperature_delta,
70
70
  cv.float_range(min=0, max=655.35),
71
71
  ),
72
72
  cv.Optional(CONF_UPDATE_INTERVAL, default="60s"): cv.All(
@@ -124,7 +124,7 @@ async def to_code(config):
124
124
  template, func_args = parameters_to_template(conf[CONF_PARAMETERS])
125
125
  trigger = cg.new_Pvariable(conf[CONF_ID], template)
126
126
  # Add a human-readable name to the script
127
- cg.add(trigger.set_name(conf[CONF_ID].id))
127
+ cg.add(trigger.set_name(cg.LogStringLiteral(conf[CONF_ID].id)))
128
128
 
129
129
  if CONF_MAX_RUNS in conf:
130
130
  cg.add(trigger.set_max_runs(conf[CONF_MAX_RUNS]))
@@ -48,14 +48,14 @@ template<typename... Ts> class Script : public ScriptLogger, public Trigger<Ts..
48
48
  }
49
49
 
50
50
  // Internal function to give scripts readable names.
51
- void set_name(const std::string &name) { name_ = name; }
51
+ void set_name(const LogString *name) { name_ = name; }
52
52
 
53
53
  protected:
54
54
  template<int... S> void execute_tuple_(const std::tuple<Ts...> &tuple, seq<S...> /*unused*/) {
55
55
  this->execute(std::get<S>(tuple)...);
56
56
  }
57
57
 
58
- std::string name_;
58
+ const LogString *name_{nullptr};
59
59
  };
60
60
 
61
61
  /** A script type for which only a single instance at a time is allowed.
@@ -68,7 +68,7 @@ template<typename... Ts> class SingleScript : public Script<Ts...> {
68
68
  void execute(Ts... x) override {
69
69
  if (this->is_action_running()) {
70
70
  this->esp_logw_(__LINE__, ESPHOME_LOG_FORMAT("Script '%s' is already running! (mode: single)"),
71
- this->name_.c_str());
71
+ LOG_STR_ARG(this->name_));
72
72
  return;
73
73
  }
74
74
 
@@ -85,7 +85,7 @@ template<typename... Ts> class RestartScript : public Script<Ts...> {
85
85
  public:
86
86
  void execute(Ts... x) override {
87
87
  if (this->is_action_running()) {
88
- this->esp_logd_(__LINE__, ESPHOME_LOG_FORMAT("Script '%s' restarting (mode: restart)"), this->name_.c_str());
88
+ this->esp_logd_(__LINE__, ESPHOME_LOG_FORMAT("Script '%s' restarting (mode: restart)"), LOG_STR_ARG(this->name_));
89
89
  this->stop_action();
90
90
  }
91
91
 
@@ -105,12 +105,12 @@ template<typename... Ts> class QueueingScript : public Script<Ts...>, public Com
105
105
  // num_runs_ + 1
106
106
  if (this->max_runs_ != 0 && this->num_runs_ + 1 >= this->max_runs_) {
107
107
  this->esp_logw_(__LINE__, ESPHOME_LOG_FORMAT("Script '%s' maximum number of queued runs exceeded!"),
108
- this->name_.c_str());
108
+ LOG_STR_ARG(this->name_));
109
109
  return;
110
110
  }
111
111
 
112
112
  this->esp_logd_(__LINE__, ESPHOME_LOG_FORMAT("Script '%s' queueing new instance (mode: queued)"),
113
- this->name_.c_str());
113
+ LOG_STR_ARG(this->name_));
114
114
  this->num_runs_++;
115
115
  this->var_queue_.push(std::make_tuple(x...));
116
116
  return;
@@ -157,7 +157,7 @@ template<typename... Ts> class ParallelScript : public Script<Ts...> {
157
157
  void execute(Ts... x) override {
158
158
  if (this->max_runs_ != 0 && this->automation_parent_->num_running() >= this->max_runs_) {
159
159
  this->esp_logw_(__LINE__, ESPHOME_LOG_FORMAT("Script '%s' maximum number of parallel runs exceeded!"),
160
- this->name_.c_str());
160
+ LOG_STR_ARG(this->name_));
161
161
  return;
162
162
  }
163
163
  this->trigger(x...);