esphome 2024.12.4__py3-none-any.whl → 2025.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (366) hide show
  1. esphome/__main__.py +16 -3
  2. esphome/components/adc/__init__.py +17 -11
  3. esphome/components/adc/adc_sensor.h +17 -0
  4. esphome/components/adc/adc_sensor_common.cpp +55 -0
  5. esphome/components/adc/adc_sensor_esp32.cpp +8 -5
  6. esphome/components/adc/adc_sensor_esp8266.cpp +10 -6
  7. esphome/components/adc/adc_sensor_libretiny.cpp +11 -6
  8. esphome/components/adc/adc_sensor_rp2040.cpp +13 -10
  9. esphome/components/adc/sensor.py +9 -3
  10. esphome/components/ads1115/ads1115.cpp +56 -7
  11. esphome/components/ads1115/ads1115.h +13 -1
  12. esphome/components/ads1115/sensor/__init__.py +16 -0
  13. esphome/components/ads1115/sensor/ads1115_sensor.cpp +2 -1
  14. esphome/components/ads1115/sensor/ads1115_sensor.h +2 -0
  15. esphome/components/animation/__init__.py +23 -261
  16. esphome/components/animation/animation.cpp +2 -2
  17. esphome/components/animation/animation.h +2 -1
  18. esphome/components/api/api_pb2.cpp +14 -0
  19. esphome/components/api/api_pb2.h +1 -0
  20. esphome/components/api/client.py +8 -3
  21. esphome/components/audio/__init__.py +112 -0
  22. esphome/components/audio/audio.cpp +67 -0
  23. esphome/components/audio/audio.h +125 -7
  24. esphome/components/audio/audio_decoder.cpp +361 -0
  25. esphome/components/audio/audio_decoder.h +135 -0
  26. esphome/components/audio/audio_reader.cpp +308 -0
  27. esphome/components/audio/audio_reader.h +85 -0
  28. esphome/components/audio/audio_resampler.cpp +159 -0
  29. esphome/components/audio/audio_resampler.h +101 -0
  30. esphome/components/audio/audio_transfer_buffer.cpp +165 -0
  31. esphome/components/audio/audio_transfer_buffer.h +139 -0
  32. esphome/components/audio_adc/__init__.py +41 -0
  33. esphome/components/audio_adc/audio_adc.h +17 -0
  34. esphome/components/audio_adc/automation.h +23 -0
  35. esphome/components/bk72xx/__init__.py +1 -0
  36. esphome/components/ble_client/ble_client.cpp +1 -2
  37. esphome/components/ble_client/sensor/__init__.py +1 -1
  38. esphome/components/ble_client/text_sensor/__init__.py +1 -1
  39. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +5 -0
  40. esphome/components/bluetooth_proxy/bluetooth_connection.h +1 -0
  41. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +5 -0
  42. esphome/components/ch422g/ch422g.h +2 -0
  43. esphome/components/climate/__init__.py +1 -1
  44. esphome/components/climate_ir/climate_ir.cpp +2 -1
  45. esphome/components/coolix/coolix.cpp +2 -1
  46. esphome/components/cse7766/cse7766.cpp +8 -16
  47. esphome/components/custom/__init__.py +0 -3
  48. esphome/components/custom/binary_sensor/__init__.py +2 -28
  49. esphome/components/custom/climate/__init__.py +2 -27
  50. esphome/components/custom/cover/__init__.py +2 -27
  51. esphome/components/custom/light/__init__.py +2 -27
  52. esphome/components/custom/output/__init__.py +2 -58
  53. esphome/components/custom/sensor/__init__.py +2 -24
  54. esphome/components/custom/switch/__init__.py +2 -24
  55. esphome/components/custom/text_sensor/__init__.py +2 -29
  56. esphome/components/custom_component/__init__.py +3 -27
  57. esphome/components/daly_bms/daly_bms.cpp +6 -0
  58. esphome/components/daly_bms/daly_bms.h +2 -0
  59. esphome/components/daly_bms/sensor.py +6 -0
  60. esphome/components/debug/debug_component.cpp +4 -0
  61. esphome/components/debug/debug_component.h +14 -0
  62. esphome/components/debug/debug_esp32.cpp +154 -74
  63. esphome/components/dfplayer/dfplayer.cpp +15 -2
  64. esphome/components/dfrobot_sen0395/dfrobot_sen0395.cpp +2 -1
  65. esphome/components/dht/dht.cpp +4 -2
  66. esphome/components/dht/sensor.py +1 -1
  67. esphome/components/display/__init__.py +18 -5
  68. esphome/components/display/display.cpp +16 -3
  69. esphome/components/display/rect.cpp +2 -1
  70. esphome/components/es7210/__init__.py +0 -0
  71. esphome/components/es7210/audio_adc.py +51 -0
  72. esphome/components/es7210/es7210.cpp +228 -0
  73. esphome/components/es7210/es7210.h +62 -0
  74. esphome/components/es7210/es7210_const.h +129 -0
  75. esphome/components/es7243e/__init__.py +0 -0
  76. esphome/components/es7243e/audio_adc.py +34 -0
  77. esphome/components/es7243e/es7243e.cpp +125 -0
  78. esphome/components/es7243e/es7243e.h +37 -0
  79. esphome/components/es7243e/es7243e_const.h +54 -0
  80. esphome/components/es8156/__init__.py +0 -0
  81. esphome/components/es8156/audio_dac.py +27 -0
  82. esphome/components/es8156/es8156.cpp +87 -0
  83. esphome/components/es8156/es8156.h +51 -0
  84. esphome/components/es8156/es8156_const.h +68 -0
  85. esphome/components/es8311/audio_dac.py +1 -2
  86. esphome/components/esp32/__init__.py +1 -0
  87. esphome/components/esp32/core.cpp +5 -1
  88. esphome/components/esp32/gpio.h +2 -0
  89. esphome/components/esp32_ble/__init__.py +39 -0
  90. esphome/components/esp32_ble/queue.h +4 -4
  91. esphome/components/esp32_ble_client/ble_client_base.cpp +46 -0
  92. esphome/components/esp32_ble_client/ble_client_base.h +2 -0
  93. esphome/components/esp32_ble_server/__init__.py +582 -12
  94. esphome/components/esp32_ble_server/ble_characteristic.cpp +48 -60
  95. esphome/components/esp32_ble_server/ble_characteristic.h +24 -17
  96. esphome/components/esp32_ble_server/ble_descriptor.cpp +21 -9
  97. esphome/components/esp32_ble_server/ble_descriptor.h +17 -6
  98. esphome/components/esp32_ble_server/ble_server.cpp +62 -67
  99. esphome/components/esp32_ble_server/ble_server.h +28 -32
  100. esphome/components/esp32_ble_server/ble_server_automations.cpp +77 -0
  101. esphome/components/esp32_ble_server/ble_server_automations.h +115 -0
  102. esphome/components/esp32_ble_server/ble_service.cpp +17 -15
  103. esphome/components/esp32_ble_server/ble_service.h +10 -14
  104. esphome/components/esp32_ble_tracker/__init__.py +6 -39
  105. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +33 -10
  106. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +8 -4
  107. esphome/components/esp32_dac/esp32_dac.cpp +16 -7
  108. esphome/components/esp32_dac/esp32_dac.h +8 -0
  109. esphome/components/esp32_dac/output.py +16 -4
  110. esphome/components/esp32_improv/__init__.py +2 -8
  111. esphome/components/esp32_improv/esp32_improv_component.cpp +21 -20
  112. esphome/components/esp32_improv/esp32_improv_component.h +3 -4
  113. esphome/components/esp32_rmt/__init__.py +28 -3
  114. esphome/components/esp32_rmt_led_strip/led_strip.cpp +73 -6
  115. esphome/components/esp32_rmt_led_strip/led_strip.h +21 -3
  116. esphome/components/esp32_rmt_led_strip/light.py +72 -7
  117. esphome/components/esp32_touch/esp32_touch.cpp +5 -0
  118. esphome/components/esp8266/__init__.py +1 -0
  119. esphome/components/esp8266/gpio.h +1 -0
  120. esphome/components/ethernet/__init__.py +10 -10
  121. esphome/components/event/event.cpp +4 -2
  122. esphome/components/event/event.h +2 -0
  123. esphome/components/event_emitter/__init__.py +5 -0
  124. esphome/components/event_emitter/event_emitter.cpp +14 -0
  125. esphome/components/event_emitter/event_emitter.h +63 -0
  126. esphome/components/font/__init__.py +1 -1
  127. esphome/components/gcja5/gcja5.cpp +2 -1
  128. esphome/components/graph/graph.cpp +4 -9
  129. esphome/components/haier/haier_base.cpp +2 -1
  130. esphome/components/haier/hon_climate.cpp +2 -1
  131. esphome/components/heatpumpir/heatpumpir.cpp +2 -1
  132. esphome/components/host/__init__.py +1 -0
  133. esphome/components/host/gpio.h +1 -0
  134. esphome/components/http_request/http_request.h +2 -2
  135. esphome/components/http_request/http_request_arduino.cpp +1 -1
  136. esphome/components/http_request/http_request_idf.cpp +1 -1
  137. esphome/components/i2c/i2c_bus_esp_idf.cpp +4 -0
  138. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +7 -5
  139. esphome/components/i2s_audio/speaker/__init__.py +53 -6
  140. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +92 -46
  141. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +8 -0
  142. esphome/components/ili9xxx/display.py +29 -11
  143. esphome/components/ili9xxx/ili9xxx_display.cpp +2 -5
  144. esphome/components/ili9xxx/ili9xxx_display.h +2 -1
  145. esphome/components/image/__init__.py +443 -255
  146. esphome/components/image/image.cpp +115 -61
  147. esphome/components/image/image.h +15 -24
  148. esphome/components/json/json_util.cpp +8 -34
  149. esphome/components/libretiny/__init__.py +1 -0
  150. esphome/components/libretiny/gpio_arduino.h +1 -0
  151. esphome/components/light/light_color_values.h +1 -1
  152. esphome/components/logger/__init__.py +45 -9
  153. esphome/components/logger/logger.cpp +16 -14
  154. esphome/components/logger/logger.h +11 -7
  155. esphome/components/logger/select/__init__.py +29 -0
  156. esphome/components/logger/select/logger_level_select.cpp +27 -0
  157. esphome/components/logger/select/logger_level_select.h +15 -0
  158. esphome/components/lvgl/__init__.py +96 -73
  159. esphome/components/lvgl/automation.py +39 -7
  160. esphome/components/lvgl/defines.py +8 -2
  161. esphome/components/lvgl/lvgl_esphome.cpp +8 -15
  162. esphome/components/lvgl/lvgl_esphome.h +20 -5
  163. esphome/components/lvgl/schemas.py +25 -14
  164. esphome/components/lvgl/trigger.py +27 -3
  165. esphome/components/lvgl/widgets/dropdown.py +1 -1
  166. esphome/components/lvgl/widgets/keyboard.py +8 -1
  167. esphome/components/lvgl/widgets/meter.py +2 -1
  168. esphome/components/lvgl/widgets/msgbox.py +1 -1
  169. esphome/components/lvgl/widgets/obj.py +1 -12
  170. esphome/components/lvgl/widgets/page.py +37 -2
  171. esphome/components/lvgl/widgets/tabview.py +1 -1
  172. esphome/components/max6956/max6956.h +2 -0
  173. esphome/components/mcp23016/mcp23016.h +2 -0
  174. esphome/components/mcp23xxx_base/mcp23xxx_base.h +2 -0
  175. esphome/components/mdns/__init__.py +1 -1
  176. esphome/components/media_player/__init__.py +37 -8
  177. esphome/components/media_player/automation.h +11 -2
  178. esphome/components/media_player/media_player.cpp +8 -0
  179. esphome/components/media_player/media_player.h +8 -4
  180. esphome/components/micronova/switch/micronova_switch.cpp +4 -2
  181. esphome/components/midea/ac_automations.h +3 -1
  182. esphome/components/midea/air_conditioner.cpp +7 -5
  183. esphome/components/midea/air_conditioner.h +1 -1
  184. esphome/components/midea/climate.py +4 -2
  185. esphome/components/midea/ir_transmitter.h +36 -5
  186. esphome/components/mixer/__init__.py +0 -0
  187. esphome/components/mixer/speaker/__init__.py +172 -0
  188. esphome/components/mixer/speaker/automation.h +19 -0
  189. esphome/components/mixer/speaker/mixer_speaker.cpp +624 -0
  190. esphome/components/mixer/speaker/mixer_speaker.h +207 -0
  191. esphome/components/modbus_controller/text_sensor/modbus_textsensor.cpp +7 -13
  192. esphome/components/mpr121/mpr121.h +2 -0
  193. esphome/components/mqtt/__init__.py +1 -1
  194. esphome/components/mqtt/mqtt_client.cpp +7 -1
  195. esphome/components/mqtt/mqtt_client.h +1 -1
  196. esphome/components/mqtt/mqtt_climate.cpp +2 -2
  197. esphome/components/network/ip_address.h +2 -0
  198. esphome/components/nextion/automation.h +17 -0
  199. esphome/components/nextion/display.py +42 -17
  200. esphome/components/nextion/nextion.cpp +4 -10
  201. esphome/components/nextion/nextion.h +89 -82
  202. esphome/components/nextion/nextion_commands.cpp +10 -10
  203. esphome/components/ntc/sensor.py +2 -4
  204. esphome/components/online_image/__init__.py +98 -46
  205. esphome/components/online_image/bmp_image.cpp +101 -0
  206. esphome/components/online_image/bmp_image.h +40 -0
  207. esphome/components/online_image/image_decoder.cpp +31 -2
  208. esphome/components/online_image/image_decoder.h +24 -15
  209. esphome/components/online_image/jpeg_image.cpp +92 -0
  210. esphome/components/online_image/jpeg_image.h +34 -0
  211. esphome/components/online_image/online_image.cpp +118 -58
  212. esphome/components/online_image/online_image.h +39 -9
  213. esphome/components/online_image/png_image.cpp +7 -3
  214. esphome/components/online_image/png_image.h +2 -1
  215. esphome/components/opentherm/__init__.py +73 -7
  216. esphome/components/opentherm/automation.h +25 -0
  217. esphome/components/opentherm/const.py +1 -0
  218. esphome/components/opentherm/generate.py +39 -6
  219. esphome/components/opentherm/hub.cpp +117 -79
  220. esphome/components/opentherm/hub.h +31 -15
  221. esphome/components/opentherm/opentherm.cpp +47 -23
  222. esphome/components/opentherm/opentherm.h +27 -6
  223. esphome/components/opentherm/opentherm_macros.h +11 -0
  224. esphome/components/opentherm/schema.py +78 -1
  225. esphome/components/opentherm/validate.py +7 -2
  226. esphome/components/pca6416a/pca6416a.h +2 -0
  227. esphome/components/pca9554/pca9554.h +2 -0
  228. esphome/components/pcf8574/pcf8574.h +2 -0
  229. esphome/components/preferences/__init__.py +2 -4
  230. esphome/components/preferences/syncer.h +10 -3
  231. esphome/components/prometheus/prometheus_handler.cpp +313 -0
  232. esphome/components/prometheus/prometheus_handler.h +48 -7
  233. esphome/components/psram/psram.cpp +8 -1
  234. esphome/components/pulse_counter/pulse_counter_sensor.cpp +14 -9
  235. esphome/components/pulse_counter/pulse_counter_sensor.h +4 -4
  236. esphome/components/pulse_meter/pulse_meter_sensor.cpp +2 -0
  237. esphome/components/qspi_dbi/__init__.py +3 -0
  238. esphome/components/qspi_dbi/display.py +74 -47
  239. esphome/components/qspi_dbi/models.py +245 -2
  240. esphome/components/qspi_dbi/qspi_dbi.cpp +9 -16
  241. esphome/components/qspi_dbi/qspi_dbi.h +2 -2
  242. esphome/components/remote_base/__init__.py +77 -25
  243. esphome/components/remote_base/remote_base.cpp +1 -1
  244. esphome/components/remote_base/remote_base.h +20 -2
  245. esphome/components/remote_base/toto_protocol.cpp +100 -0
  246. esphome/components/remote_base/toto_protocol.h +45 -0
  247. esphome/components/remote_receiver/__init__.py +55 -10
  248. esphome/components/remote_receiver/remote_receiver.h +36 -3
  249. esphome/components/remote_receiver/remote_receiver_esp32.cpp +145 -6
  250. esphome/components/remote_transmitter/__init__.py +62 -4
  251. esphome/components/remote_transmitter/remote_transmitter.h +21 -2
  252. esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +140 -4
  253. esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +3 -3
  254. esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +3 -3
  255. esphome/components/resampler/__init__.py +0 -0
  256. esphome/components/resampler/speaker/__init__.py +103 -0
  257. esphome/components/resampler/speaker/resampler_speaker.cpp +318 -0
  258. esphome/components/resampler/speaker/resampler_speaker.h +107 -0
  259. esphome/components/resistance/resistance_sensor.h +2 -3
  260. esphome/components/resistance/sensor.py +2 -9
  261. esphome/components/rotary_encoder/rotary_encoder.cpp +8 -4
  262. esphome/components/rp2040/__init__.py +1 -0
  263. esphome/components/rp2040/gpio.h +1 -0
  264. esphome/components/rtl87xx/__init__.py +2 -0
  265. esphome/components/scd30/sensor.py +1 -1
  266. esphome/components/sdl/binary_sensor.py +270 -0
  267. esphome/components/sdl/sdl_esphome.cpp +16 -0
  268. esphome/components/sdl/sdl_esphome.h +9 -0
  269. esphome/components/seeed_mr60bha2/binary_sensor.py +25 -0
  270. esphome/components/seeed_mr60bha2/seeed_mr60bha2.cpp +26 -2
  271. esphome/components/seeed_mr60bha2/seeed_mr60bha2.h +9 -20
  272. esphome/components/seeed_mr60bha2/sensor.py +9 -1
  273. esphome/components/sn74hc165/sn74hc165.h +3 -0
  274. esphome/components/sn74hc595/sn74hc595.h +3 -0
  275. esphome/components/speaker/__init__.py +5 -4
  276. esphome/components/speaker/media_player/__init__.py +458 -0
  277. esphome/components/speaker/media_player/audio_pipeline.cpp +568 -0
  278. esphome/components/speaker/media_player/audio_pipeline.h +159 -0
  279. esphome/components/speaker/media_player/automation.h +26 -0
  280. esphome/components/speaker/media_player/speaker_media_player.cpp +577 -0
  281. esphome/components/speaker/media_player/speaker_media_player.h +160 -0
  282. esphome/components/speaker/speaker.h +20 -0
  283. esphome/components/spi/__init__.py +1 -5
  284. esphome/components/spi/spi.cpp +7 -1
  285. esphome/components/spi/spi.h +21 -2
  286. esphome/components/spi_led_strip/light.py +3 -5
  287. esphome/components/spi_led_strip/spi_led_strip.cpp +67 -0
  288. esphome/components/spi_led_strip/spi_led_strip.h +8 -60
  289. esphome/components/sprinkler/sprinkler.cpp +3 -1
  290. esphome/components/sx1509/sx1509_gpio_pin.h +2 -0
  291. esphome/components/tca9555/tca9555.h +2 -0
  292. esphome/components/toshiba/toshiba.cpp +2 -1
  293. esphome/components/tuya/light/tuya_light.cpp +4 -2
  294. esphome/components/uart/uart_component_esp32_arduino.cpp +2 -2
  295. esphome/components/uart/uart_component_esp_idf.cpp +2 -2
  296. esphome/components/udp/__init__.py +8 -2
  297. esphome/components/udp/udp_component.cpp +25 -56
  298. esphome/components/udp/udp_component.h +3 -0
  299. esphome/components/uponor_smatrix/sensor/__init__.py +14 -4
  300. esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.cpp +5 -0
  301. esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.h +1 -0
  302. esphome/components/uptime/text_sensor/__init__.py +19 -0
  303. esphome/components/uptime/text_sensor/uptime_text_sensor.cpp +63 -0
  304. esphome/components/uptime/text_sensor/uptime_text_sensor.h +25 -0
  305. esphome/components/voice_assistant/voice_assistant.cpp +24 -14
  306. esphome/components/voice_assistant/voice_assistant.h +8 -0
  307. esphome/components/waveshare_epaper/display.py +22 -1
  308. esphome/components/waveshare_epaper/waveshare_213v3.cpp +9 -3
  309. esphome/components/waveshare_epaper/waveshare_epaper.cpp +1155 -44
  310. esphome/components/waveshare_epaper/waveshare_epaper.h +208 -7
  311. esphome/components/web_server/web_server.cpp +28 -6
  312. esphome/components/weikai/weikai.h +2 -0
  313. esphome/components/wifi/__init__.py +6 -6
  314. esphome/components/wifi/wifi_component.cpp +1 -1
  315. esphome/components/wifi/wifi_component_esp32_arduino.cpp +30 -1
  316. esphome/components/wireguard/__init__.py +2 -2
  317. esphome/components/xl9535/xl9535.h +2 -0
  318. esphome/components/xxtea/__init__.py +3 -0
  319. esphome/components/xxtea/xxtea.cpp +46 -0
  320. esphome/components/xxtea/xxtea.h +26 -0
  321. esphome/components/yashima/yashima.cpp +2 -1
  322. esphome/config.py +9 -5
  323. esphome/config_validation.py +55 -17
  324. esphome/const.py +7 -10
  325. esphome/core/__init__.py +6 -13
  326. esphome/core/base_automation.h +1 -0
  327. esphome/core/config.py +59 -72
  328. esphome/core/defines.h +9 -1
  329. esphome/core/gpio.h +7 -0
  330. esphome/core/helpers.cpp +19 -15
  331. esphome/core/helpers.h +57 -8
  332. esphome/core/log.h +9 -7
  333. esphome/cpp_generator.py +2 -2
  334. esphome/dashboard/web_server.py +1 -1
  335. esphome/espota2.py +3 -2
  336. esphome/loader.py +12 -4
  337. esphome/log.py +5 -7
  338. esphome/yaml_util.py +2 -2
  339. {esphome-2024.12.4.dist-info → esphome-2025.2.0.dist-info}/METADATA +14 -9
  340. {esphome-2024.12.4.dist-info → esphome-2025.2.0.dist-info}/RECORD +349 -300
  341. esphome/components/custom/binary_sensor/custom_binary_sensor.cpp +0 -16
  342. esphome/components/custom/binary_sensor/custom_binary_sensor.h +0 -26
  343. esphome/components/custom/climate/custom_climate.h +0 -22
  344. esphome/components/custom/cover/custom_cover.h +0 -21
  345. esphome/components/custom/light/custom_light_output.h +0 -24
  346. esphome/components/custom/output/custom_output.h +0 -37
  347. esphome/components/custom/sensor/custom_sensor.cpp +0 -16
  348. esphome/components/custom/sensor/custom_sensor.h +0 -24
  349. esphome/components/custom/switch/custom_switch.cpp +0 -16
  350. esphome/components/custom/switch/custom_switch.h +0 -24
  351. esphome/components/custom/text_sensor/custom_text_sensor.cpp +0 -16
  352. esphome/components/custom/text_sensor/custom_text_sensor.h +0 -26
  353. esphome/components/custom_component/custom_component.h +0 -28
  354. esphome/components/esp32_ble_server/ble_2901.cpp +0 -18
  355. esphome/components/esp32_ble_server/ble_2901.h +0 -19
  356. esphome/components/resistance_sampler/__init__.py +0 -6
  357. esphome/components/resistance_sampler/resistance_sampler.h +0 -10
  358. esphome/components/uptime/{sensor.py → sensor/__init__.py} +3 -3
  359. /esphome/components/uptime/{uptime_seconds_sensor.cpp → sensor/uptime_seconds_sensor.cpp} +0 -0
  360. /esphome/components/uptime/{uptime_seconds_sensor.h → sensor/uptime_seconds_sensor.h} +0 -0
  361. /esphome/components/uptime/{uptime_timestamp_sensor.cpp → sensor/uptime_timestamp_sensor.cpp} +0 -0
  362. /esphome/components/uptime/{uptime_timestamp_sensor.h → sensor/uptime_timestamp_sensor.h} +0 -0
  363. {esphome-2024.12.4.dist-info → esphome-2025.2.0.dist-info}/LICENSE +0 -0
  364. {esphome-2024.12.4.dist-info → esphome-2025.2.0.dist-info}/WHEEL +0 -0
  365. {esphome-2024.12.4.dist-info → esphome-2025.2.0.dist-info}/entry_points.txt +0 -0
  366. {esphome-2024.12.4.dist-info → esphome-2025.2.0.dist-info}/top_level.txt +0 -0
@@ -52,7 +52,9 @@ bool OpenTherm::initialize() {
52
52
  OpenTherm::instance = this;
53
53
  #endif
54
54
  this->in_pin_->pin_mode(gpio::FLAG_INPUT);
55
+ this->in_pin_->setup();
55
56
  this->out_pin_->pin_mode(gpio::FLAG_OUTPUT);
57
+ this->out_pin_->setup();
56
58
  this->out_pin_->digital_write(true);
57
59
 
58
60
  #if defined(ESP32) || defined(USE_ESP_IDF)
@@ -182,7 +184,7 @@ bool IRAM_ATTR OpenTherm::timer_isr(OpenTherm *arg) {
182
184
  }
183
185
  arg->capture_ = 1; // reset counter
184
186
  } else if (arg->capture_ > 0xFF) {
185
- // no change for too long, invalid mancheter encoding
187
+ // no change for too long, invalid manchester encoding
186
188
  arg->mode_ = OperationMode::ERROR_PROTOCOL;
187
189
  arg->error_type_ = ProtocolErrorType::NO_CHANGE_TOO_LONG;
188
190
  arg->stop_timer_();
@@ -312,21 +314,31 @@ bool OpenTherm::init_esp32_timer_() {
312
314
  }
313
315
 
314
316
  void IRAM_ATTR OpenTherm::start_esp32_timer_(uint64_t alarm_value) {
315
- esp_err_t result;
317
+ // We will report timer errors outside of interrupt handler
318
+ this->timer_error_ = ESP_OK;
319
+ this->timer_error_type_ = TimerErrorType::NO_TIMER_ERROR;
316
320
 
317
- result = timer_set_alarm_value(this->timer_group_, this->timer_idx_, alarm_value);
318
- if (result != ESP_OK) {
319
- const auto *error = esp_err_to_name(result);
320
- ESP_LOGE(TAG, "Failed to set alarm value. Error: %s", error);
321
+ this->timer_error_ = timer_set_alarm_value(this->timer_group_, this->timer_idx_, alarm_value);
322
+ if (this->timer_error_ != ESP_OK) {
323
+ this->timer_error_type_ = TimerErrorType::SET_ALARM_VALUE_ERROR;
321
324
  return;
322
325
  }
326
+ this->timer_error_ = timer_start(this->timer_group_, this->timer_idx_);
327
+ if (this->timer_error_ != ESP_OK) {
328
+ this->timer_error_type_ = TimerErrorType::TIMER_START_ERROR;
329
+ }
330
+ }
323
331
 
324
- result = timer_start(this->timer_group_, this->timer_idx_);
325
- if (result != ESP_OK) {
326
- const auto *error = esp_err_to_name(result);
327
- ESP_LOGE(TAG, "Failed to start the timer. Error: %s", error);
332
+ void OpenTherm::report_and_reset_timer_error() {
333
+ if (this->timer_error_ == ESP_OK) {
328
334
  return;
329
335
  }
336
+
337
+ ESP_LOGE(TAG, "Error occured while manipulating timer (%s): %s", this->timer_error_to_str(this->timer_error_type_),
338
+ esp_err_to_name(this->timer_error_));
339
+
340
+ this->timer_error_ = ESP_OK;
341
+ this->timer_error_type_ = NO_TIMER_ERROR;
330
342
  }
331
343
 
332
344
  // 5 kHz timer_
@@ -343,21 +355,18 @@ void IRAM_ATTR OpenTherm::start_write_timer_() {
343
355
 
344
356
  void IRAM_ATTR OpenTherm::stop_timer_() {
345
357
  InterruptLock const lock;
358
+ // We will report timer errors outside of interrupt handler
359
+ this->timer_error_ = ESP_OK;
360
+ this->timer_error_type_ = TimerErrorType::NO_TIMER_ERROR;
346
361
 
347
- esp_err_t result;
348
-
349
- result = timer_pause(this->timer_group_, this->timer_idx_);
350
- if (result != ESP_OK) {
351
- const auto *error = esp_err_to_name(result);
352
- ESP_LOGE(TAG, "Failed to pause the timer. Error: %s", error);
362
+ this->timer_error_ = timer_pause(this->timer_group_, this->timer_idx_);
363
+ if (this->timer_error_ != ESP_OK) {
364
+ this->timer_error_type_ = TimerErrorType::TIMER_PAUSE_ERROR;
353
365
  return;
354
366
  }
355
-
356
- result = timer_set_counter_value(this->timer_group_, this->timer_idx_, 0);
357
- if (result != ESP_OK) {
358
- const auto *error = esp_err_to_name(result);
359
- ESP_LOGE(TAG, "Failed to set timer counter to 0 after pausing. Error: %s", error);
360
- return;
367
+ this->timer_error_ = timer_set_counter_value(this->timer_group_, this->timer_idx_, 0);
368
+ if (this->timer_error_ != ESP_OK) {
369
+ this->timer_error_type_ = TimerErrorType::SET_COUNTER_VALUE_ERROR;
361
370
  }
362
371
  }
363
372
 
@@ -386,6 +395,9 @@ void IRAM_ATTR OpenTherm::stop_timer_() {
386
395
  timer1_detachInterrupt();
387
396
  }
388
397
 
398
+ // There is nothing to report on ESP8266
399
+ void OpenTherm::report_and_reset_timer_error() {}
400
+
389
401
  #endif // END ESP8266
390
402
 
391
403
  // https://stackoverflow.com/questions/21617970/how-to-check-if-value-has-even-parity-of-bits-or-odd
@@ -412,11 +424,12 @@ const char *OpenTherm::operation_mode_to_str(OperationMode mode) {
412
424
  TO_STRING_MEMBER(SENT)
413
425
  TO_STRING_MEMBER(ERROR_PROTOCOL)
414
426
  TO_STRING_MEMBER(ERROR_TIMEOUT)
427
+ TO_STRING_MEMBER(ERROR_TIMER)
415
428
  default:
416
429
  return "<INVALID>";
417
430
  }
418
431
  }
419
- const char *OpenTherm::protocol_error_to_to_str(ProtocolErrorType error_type) {
432
+ const char *OpenTherm::protocol_error_to_str(ProtocolErrorType error_type) {
420
433
  switch (error_type) {
421
434
  TO_STRING_MEMBER(NO_ERROR)
422
435
  TO_STRING_MEMBER(NO_TRANSITION)
@@ -427,6 +440,17 @@ const char *OpenTherm::protocol_error_to_to_str(ProtocolErrorType error_type) {
427
440
  return "<INVALID>";
428
441
  }
429
442
  }
443
+ const char *OpenTherm::timer_error_to_str(TimerErrorType error_type) {
444
+ switch (error_type) {
445
+ TO_STRING_MEMBER(NO_TIMER_ERROR)
446
+ TO_STRING_MEMBER(SET_ALARM_VALUE_ERROR)
447
+ TO_STRING_MEMBER(TIMER_START_ERROR)
448
+ TO_STRING_MEMBER(TIMER_PAUSE_ERROR)
449
+ TO_STRING_MEMBER(SET_COUNTER_VALUE_ERROR)
450
+ default:
451
+ return "<INVALID>";
452
+ }
453
+ }
430
454
  const char *OpenTherm::message_type_to_str(MessageType message_type) {
431
455
  switch (message_type) {
432
456
  TO_STRING_MEMBER(READ_DATA)
@@ -36,11 +36,12 @@ enum OperationMode {
36
36
  READ = 2, // reading 32-bit data frame
37
37
  RECEIVED = 3, // data frame received with valid start and stop bit
38
38
 
39
- WRITE = 4, // writing data with timer_
39
+ WRITE = 4, // writing data to output
40
40
  SENT = 5, // all data written to output
41
41
 
42
- ERROR_PROTOCOL = 8, // manchester protocol data transfer error
43
- ERROR_TIMEOUT = 9 // read timeout
42
+ ERROR_PROTOCOL = 8, // protocol error, can happed only during READ
43
+ ERROR_TIMEOUT = 9, // timeout while waiting for response from device, only during LISTEN
44
+ ERROR_TIMER = 10 // error operating the ESP32 timer
44
45
  };
45
46
 
46
47
  enum ProtocolErrorType {
@@ -51,6 +52,14 @@ enum ProtocolErrorType {
51
52
  NO_CHANGE_TOO_LONG = 4, // No level change for too much timer ticks
52
53
  };
53
54
 
55
+ enum TimerErrorType {
56
+ NO_TIMER_ERROR = 0, // No error
57
+ SET_ALARM_VALUE_ERROR = 1, // No transition in the middle of the bit
58
+ TIMER_START_ERROR = 2, // Stop bit wasn't present when expected
59
+ TIMER_PAUSE_ERROR = 3, // Parity check didn't pass
60
+ SET_COUNTER_VALUE_ERROR = 4, // No level change for too much timer ticks
61
+ };
62
+
54
63
  enum MessageType {
55
64
  READ_DATA = 0,
56
65
  READ_ACK = 4,
@@ -299,7 +308,9 @@ class OpenTherm {
299
308
  *
300
309
  * @return true if last listen() or send() operation ends up with an error.
301
310
  */
302
- bool is_error() { return mode_ == OperationMode::ERROR_TIMEOUT || mode_ == OperationMode::ERROR_PROTOCOL; }
311
+ bool is_error() {
312
+ return mode_ == OperationMode::ERROR_TIMEOUT || mode_ == OperationMode::ERROR_PROTOCOL || mode_ == ERROR_TIMER;
313
+ }
303
314
 
304
315
  /**
305
316
  * Indicates whether last listen() or send() operation ends up with a *timeout* error
@@ -313,14 +324,22 @@ class OpenTherm {
313
324
  */
314
325
  bool is_protocol_error() { return mode_ == OperationMode::ERROR_PROTOCOL; }
315
326
 
327
+ /**
328
+ * Indicates whether start_esp32_timer_() or stop_timer_() had an error. Only relevant when used on ESP32.
329
+ * @return true if there was an error.
330
+ */
331
+ bool is_timer_error() { return mode_ == OperationMode::ERROR_TIMER; }
332
+
316
333
  bool is_active() { return mode_ == LISTEN || mode_ == READ || mode_ == WRITE; }
317
334
 
318
335
  OperationMode get_mode() { return mode_; }
319
336
 
320
337
  void debug_data(OpenthermData &data);
321
338
  void debug_error(OpenThermError &error) const;
339
+ void report_and_reset_timer_error();
322
340
 
323
- const char *protocol_error_to_to_str(ProtocolErrorType error_type);
341
+ const char *protocol_error_to_str(ProtocolErrorType error_type);
342
+ const char *timer_error_to_str(TimerErrorType error_type);
324
343
  const char *message_type_to_str(MessageType message_type);
325
344
  const char *operation_mode_to_str(OperationMode mode);
326
345
  const char *message_id_to_str(MessageId id);
@@ -349,10 +368,12 @@ class OpenTherm {
349
368
  uint32_t data_;
350
369
  uint8_t bit_pos_;
351
370
  int32_t timeout_counter_; // <0 no timeout
352
-
353
371
  int32_t device_timeout_;
354
372
 
355
373
  #if defined(ESP32) || defined(USE_ESP_IDF)
374
+ esp_err_t timer_error_ = ESP_OK;
375
+ TimerErrorType timer_error_type_ = TimerErrorType::NO_TIMER_ERROR;
376
+
356
377
  bool init_esp32_timer_();
357
378
  void start_esp32_timer_(uint64_t alarm_value);
358
379
  #endif
@@ -28,6 +28,9 @@ namespace opentherm {
28
28
  #ifndef OPENTHERM_INPUT_SENSOR_LIST
29
29
  #define OPENTHERM_INPUT_SENSOR_LIST(F, sep)
30
30
  #endif
31
+ #ifndef OPENTHERM_SETTING_LIST
32
+ #define OPENTHERM_SETTING_LIST(F, sep)
33
+ #endif
31
34
 
32
35
  // Use macros to create fields for every entity specified in the ESPHome configuration
33
36
  #define OPENTHERM_DECLARE_SENSOR(entity) sensor::Sensor *entity;
@@ -36,6 +39,7 @@ namespace opentherm {
36
39
  #define OPENTHERM_DECLARE_NUMBER(entity) OpenthermNumber *entity;
37
40
  #define OPENTHERM_DECLARE_OUTPUT(entity) OpenthermOutput *entity;
38
41
  #define OPENTHERM_DECLARE_INPUT_SENSOR(entity) sensor::Sensor *entity;
42
+ #define OPENTHERM_DECLARE_SETTING(type, entity, def) type entity = def;
39
43
 
40
44
  // Setter macros
41
45
  #define OPENTHERM_SET_SENSOR(entity) \
@@ -56,6 +60,9 @@ namespace opentherm {
56
60
  #define OPENTHERM_SET_INPUT_SENSOR(entity) \
57
61
  void set_##entity(sensor::Sensor *sensor) { this->entity = sensor; }
58
62
 
63
+ #define OPENTHERM_SET_SETTING(type, entity, def) \
64
+ void set_##entity(type value) { this->entity = value; }
65
+
59
66
  // ===== hub.cpp macros =====
60
67
 
61
68
  // *_MESSAGE_HANDLERS are generated in defines.h and look like this:
@@ -85,6 +92,9 @@ namespace opentherm {
85
92
  #ifndef OPENTHERM_INPUT_SENSOR_MESSAGE_HANDLERS
86
93
  #define OPENTHERM_INPUT_SENSOR_MESSAGE_HANDLERS(MESSAGE, ENTITY, entity_sep, postscript, msg_sep)
87
94
  #endif
95
+ #ifndef OPENTHERM_SETTING_MESSAGE_HANDLERS
96
+ #define OPENTHERM_SETTING_MESSAGE_HANDLERS(MESSAGE, ENTITY, entity_sep, postscript, msg_sep)
97
+ #endif
88
98
 
89
99
  // Write data request builders
90
100
  #define OPENTHERM_MESSAGE_WRITE_MESSAGE(msg) \
@@ -92,6 +102,7 @@ namespace opentherm {
92
102
  data.type = MessageType::WRITE_DATA; \
93
103
  data.id = request_id;
94
104
  #define OPENTHERM_MESSAGE_WRITE_ENTITY(key, msg_data) message_data::write_##msg_data(this->key->state, data);
105
+ #define OPENTHERM_MESSAGE_WRITE_SETTING(key, msg_data) message_data::write_##msg_data(this->key, data);
95
106
  #define OPENTHERM_MESSAGE_WRITE_POSTSCRIPT \
96
107
  return data; \
97
108
  }
@@ -2,8 +2,9 @@
2
2
  # inputs of the OpenTherm component.
3
3
 
4
4
  from dataclasses import dataclass
5
- from typing import Optional, TypeVar
5
+ from typing import Optional, TypeVar, Any
6
6
 
7
+ import esphome.config_validation as cv
7
8
  from esphome.const import (
8
9
  UNIT_CELSIUS,
9
10
  UNIT_EMPTY,
@@ -64,6 +65,7 @@ class SensorSchema(EntitySchema):
64
65
  icon: Optional[str] = None
65
66
  device_class: Optional[str] = None
66
67
  disabled_by_default: bool = False
68
+ order: Optional[int] = None
67
69
 
68
70
 
69
71
  SENSORS: dict[str, SensorSchema] = {
@@ -399,6 +401,7 @@ SENSORS: dict[str, SensorSchema] = {
399
401
  message="OT_VERSION_DEVICE",
400
402
  keep_updated=False,
401
403
  message_data="f88",
404
+ order=2,
402
405
  ),
403
406
  "device_type": SensorSchema(
404
407
  description="Device product type",
@@ -409,6 +412,7 @@ SENSORS: dict[str, SensorSchema] = {
409
412
  message="VERSION_DEVICE",
410
413
  keep_updated=False,
411
414
  message_data="u8_hb",
415
+ order=0,
412
416
  ),
413
417
  "device_version": SensorSchema(
414
418
  description="Device product version",
@@ -419,6 +423,7 @@ SENSORS: dict[str, SensorSchema] = {
419
423
  message="VERSION_DEVICE",
420
424
  keep_updated=False,
421
425
  message_data="u8_lb",
426
+ order=0,
422
427
  ),
423
428
  "device_id": SensorSchema(
424
429
  description="Device ID code",
@@ -429,6 +434,7 @@ SENSORS: dict[str, SensorSchema] = {
429
434
  message="DEVICE_CONFIG",
430
435
  keep_updated=False,
431
436
  message_data="u8_lb",
437
+ order=4,
432
438
  ),
433
439
  "otc_hc_ratio_ub": SensorSchema(
434
440
  description="OTC heat curve ratio upper bound",
@@ -457,6 +463,7 @@ SENSORS: dict[str, SensorSchema] = {
457
463
  class BinarySensorSchema(EntitySchema):
458
464
  icon: Optional[str] = None
459
465
  device_class: Optional[str] = None
466
+ order: Optional[int] = None
460
467
 
461
468
 
462
469
  BINARY_SENSORS: dict[str, BinarySensorSchema] = {
@@ -525,48 +532,56 @@ BINARY_SENSORS: dict[str, BinarySensorSchema] = {
525
532
  message="DEVICE_CONFIG",
526
533
  keep_updated=False,
527
534
  message_data="flag8_hb_0",
535
+ order=4,
528
536
  ),
529
537
  "control_type_on_off": BinarySensorSchema(
530
538
  description="Configuration: Control type is on/off",
531
539
  message="DEVICE_CONFIG",
532
540
  keep_updated=False,
533
541
  message_data="flag8_hb_1",
542
+ order=4,
534
543
  ),
535
544
  "cooling_supported": BinarySensorSchema(
536
545
  description="Configuration: Cooling supported",
537
546
  message="DEVICE_CONFIG",
538
547
  keep_updated=False,
539
548
  message_data="flag8_hb_2",
549
+ order=4,
540
550
  ),
541
551
  "dhw_storage_tank": BinarySensorSchema(
542
552
  description="Configuration: DHW storage tank",
543
553
  message="DEVICE_CONFIG",
544
554
  keep_updated=False,
545
555
  message_data="flag8_hb_3",
556
+ order=4,
546
557
  ),
547
558
  "controller_pump_control_allowed": BinarySensorSchema(
548
559
  description="Configuration: Controller pump control allowed",
549
560
  message="DEVICE_CONFIG",
550
561
  keep_updated=False,
551
562
  message_data="flag8_hb_4",
563
+ order=4,
552
564
  ),
553
565
  "ch2_present": BinarySensorSchema(
554
566
  description="Configuration: CH2 present",
555
567
  message="DEVICE_CONFIG",
556
568
  keep_updated=False,
557
569
  message_data="flag8_hb_5",
570
+ order=4,
558
571
  ),
559
572
  "water_filling": BinarySensorSchema(
560
573
  description="Configuration: Remote water filling",
561
574
  message="DEVICE_CONFIG",
562
575
  keep_updated=False,
563
576
  message_data="flag8_hb_6",
577
+ order=4,
564
578
  ),
565
579
  "heat_mode": BinarySensorSchema(
566
580
  description="Configuration: Heating or cooling",
567
581
  message="DEVICE_CONFIG",
568
582
  keep_updated=False,
569
583
  message_data="flag8_hb_7",
584
+ order=4,
570
585
  ),
571
586
  "dhw_setpoint_transfer_enabled": BinarySensorSchema(
572
587
  description="Remote boiler parameters: DHW setpoint transfer enabled",
@@ -812,3 +827,65 @@ INPUTS: dict[str, InputSchema] = {
812
827
  auto_max_value=AutoConfigure(message="OTC_CURVE_BOUNDS", message_data="u8_hb"),
813
828
  ),
814
829
  }
830
+
831
+
832
+ @dataclass
833
+ class SettingSchema(EntitySchema):
834
+ backing_type: str
835
+ validation_schema: cv.Schema
836
+ default_value: Any
837
+ order: Optional[int] = None
838
+
839
+
840
+ SETTINGS: dict[str, SettingSchema] = {
841
+ "controller_product_type": SettingSchema(
842
+ description="Controller product type",
843
+ message="VERSION_CONTROLLER",
844
+ keep_updated=False,
845
+ message_data="u8_hb",
846
+ backing_type="uint8_t",
847
+ validation_schema=cv.int_range(min=0, max=255),
848
+ default_value=0,
849
+ order=1,
850
+ ),
851
+ "controller_product_version": SettingSchema(
852
+ description="Controller product version",
853
+ message="VERSION_CONTROLLER",
854
+ keep_updated=False,
855
+ message_data="u8_lb",
856
+ backing_type="uint8_t",
857
+ validation_schema=cv.int_range(min=0, max=255),
858
+ default_value=0,
859
+ order=1,
860
+ ),
861
+ "opentherm_version_controller": SettingSchema(
862
+ description="Version of OpenTherm implemented by controller",
863
+ message="OT_VERSION_CONTROLLER",
864
+ keep_updated=False,
865
+ message_data="f88",
866
+ backing_type="float",
867
+ validation_schema=cv.positive_float,
868
+ default_value=0,
869
+ order=3,
870
+ ),
871
+ "controller_configuration": SettingSchema(
872
+ description="Controller configuration",
873
+ message="CONTROLLER_CONFIG",
874
+ keep_updated=False,
875
+ message_data="u8_hb",
876
+ backing_type="uint8_t",
877
+ validation_schema=cv.int_range(min=0, max=255),
878
+ default_value=0,
879
+ order=5,
880
+ ),
881
+ "controller_id": SettingSchema(
882
+ description="Controller ID code",
883
+ message="CONTROLLER_CONFIG",
884
+ keep_updated=False,
885
+ message_data="u8_lb",
886
+ backing_type="uint8_t",
887
+ validation_schema=cv.int_range(min=0, max=255),
888
+ default_value=0,
889
+ order=5,
890
+ ),
891
+ }
@@ -9,12 +9,17 @@ from .schema import TSchema
9
9
 
10
10
 
11
11
  def create_entities_schema(
12
- entities: dict[str, schema.EntitySchema],
12
+ entities: dict[str, TSchema],
13
13
  get_entity_validation_schema: Callable[[TSchema], cv.Schema],
14
14
  ) -> Schema:
15
15
  entity_schema = {}
16
16
  for key, entity in entities.items():
17
- entity_schema[cv.Optional(key)] = get_entity_validation_schema(entity)
17
+ schema_key = (
18
+ cv.Optional(key, entity.default_value)
19
+ if hasattr(entity, "default_value")
20
+ else cv.Optional(key)
21
+ )
22
+ entity_schema[schema_key] = get_entity_validation_schema(entity)
18
23
  return cv.Schema(entity_schema)
19
24
 
20
25
 
@@ -52,6 +52,8 @@ class PCA6416AGPIOPin : public GPIOPin {
52
52
  void set_inverted(bool inverted) { inverted_ = inverted; }
53
53
  void set_flags(gpio::Flags flags) { flags_ = flags; }
54
54
 
55
+ gpio::Flags get_flags() const override { return this->flags_; }
56
+
55
57
  protected:
56
58
  PCA6416AComponent *parent_;
57
59
  uint8_t pin_;
@@ -65,6 +65,8 @@ class PCA9554GPIOPin : public GPIOPin {
65
65
  void set_inverted(bool inverted) { inverted_ = inverted; }
66
66
  void set_flags(gpio::Flags flags) { flags_ = flags; }
67
67
 
68
+ gpio::Flags get_flags() const override { return this->flags_; }
69
+
68
70
  protected:
69
71
  PCA9554Component *parent_;
70
72
  uint8_t pin_;
@@ -54,6 +54,8 @@ class PCF8574GPIOPin : public GPIOPin {
54
54
  void set_inverted(bool inverted) { inverted_ = inverted; }
55
55
  void set_flags(gpio::Flags flags) { flags_ = flags; }
56
56
 
57
+ gpio::Flags get_flags() const override { return this->flags_; }
58
+
57
59
  protected:
58
60
  PCF8574Component *parent_;
59
61
  uint8_t pin_;
@@ -1,6 +1,6 @@
1
- from esphome.const import CONF_ID
2
1
  import esphome.codegen as cg
3
2
  import esphome.config_validation as cv
3
+ from esphome.const import CONF_ID
4
4
 
5
5
  CODEOWNERS = ["@esphome/core"]
6
6
 
@@ -11,9 +11,7 @@ CONF_FLASH_WRITE_INTERVAL = "flash_write_interval"
11
11
  CONFIG_SCHEMA = cv.Schema(
12
12
  {
13
13
  cv.GenerateID(): cv.declare_id(IntervalSyncer),
14
- cv.Optional(
15
- CONF_FLASH_WRITE_INTERVAL, default="60s"
16
- ): cv.positive_time_period_milliseconds,
14
+ cv.Optional(CONF_FLASH_WRITE_INTERVAL, default="60s"): cv.update_interval,
17
15
  }
18
16
  ).extend(cv.COMPONENT_SCHEMA)
19
17
 
@@ -8,15 +8,22 @@ namespace preferences {
8
8
 
9
9
  class IntervalSyncer : public Component {
10
10
  public:
11
- void set_write_interval(uint32_t write_interval) { write_interval_ = write_interval; }
11
+ void set_write_interval(uint32_t write_interval) { this->write_interval_ = write_interval; }
12
12
  void setup() override {
13
- set_interval(write_interval_, []() { global_preferences->sync(); });
13
+ if (this->write_interval_ != 0) {
14
+ set_interval(this->write_interval_, []() { global_preferences->sync(); });
15
+ }
16
+ }
17
+ void loop() override {
18
+ if (this->write_interval_ == 0) {
19
+ global_preferences->sync();
20
+ }
14
21
  }
15
22
  void on_shutdown() override { global_preferences->sync(); }
16
23
  float get_setup_priority() const override { return setup_priority::BUS; }
17
24
 
18
25
  protected:
19
- uint32_t write_interval_;
26
+ uint32_t write_interval_{60000};
20
27
  };
21
28
 
22
29
  } // namespace preferences