esphome 2025.8.4__py3-none-any.whl → 2025.9.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 (369) hide show
  1. esphome/__main__.py +177 -105
  2. esphome/components/absolute_humidity/absolute_humidity.cpp +3 -5
  3. esphome/components/adc/__init__.py +1 -26
  4. esphome/components/adc/adc_sensor_esp32.cpp +29 -6
  5. esphome/components/adc/sensor.py +20 -0
  6. esphome/components/ade7880/ade7880.cpp +1 -1
  7. esphome/components/ags10/ags10.cpp +3 -18
  8. esphome/components/ags10/ags10.h +2 -12
  9. esphome/components/aht10/aht10.cpp +3 -3
  10. esphome/components/airthings_ble/__init__.py +2 -2
  11. esphome/components/alarm_control_panel/__init__.py +2 -2
  12. esphome/components/am2315c/am2315c.cpp +1 -17
  13. esphome/components/am2315c/am2315c.h +2 -3
  14. esphome/components/api/__init__.py +2 -2
  15. esphome/components/api/api_connection.cpp +38 -34
  16. esphome/components/api/api_connection.h +20 -40
  17. esphome/components/api/api_frame_helper.cpp +25 -25
  18. esphome/components/api/api_frame_helper.h +3 -3
  19. esphome/components/api/api_frame_helper_noise.cpp +75 -40
  20. esphome/components/api/api_frame_helper_noise.h +3 -7
  21. esphome/components/api/api_frame_helper_plaintext.cpp +17 -4
  22. esphome/components/api/api_frame_helper_plaintext.h +1 -4
  23. esphome/components/api/api_pb2.cpp +12 -2
  24. esphome/components/api/api_pb2.h +144 -143
  25. esphome/components/api/api_pb2_dump.cpp +6 -1
  26. esphome/components/api/api_pb2_service.cpp +0 -14
  27. esphome/components/api/api_pb2_service.h +1 -3
  28. esphome/components/api/client.py +5 -3
  29. esphome/components/api/proto.cpp +33 -37
  30. esphome/components/async_tcp/__init__.py +2 -2
  31. esphome/components/atm90e26/sensor.py +2 -0
  32. esphome/components/atm90e32/sensor.py +4 -2
  33. esphome/components/audio_adc/__init__.py +2 -2
  34. esphome/components/audio_dac/__init__.py +2 -2
  35. esphome/components/axs15231/touchscreen/axs15231_touchscreen.cpp +1 -1
  36. esphome/components/bedjet/bedjet_hub.cpp +1 -1
  37. esphome/components/binary_sensor/__init__.py +2 -2
  38. esphome/components/binary_sensor/binary_sensor.cpp +13 -0
  39. esphome/components/binary_sensor/binary_sensor.h +4 -7
  40. esphome/components/bl0940/__init__.py +6 -1
  41. esphome/components/bl0940/bl0940.cpp +178 -41
  42. esphome/components/bl0940/bl0940.h +121 -76
  43. esphome/components/bl0940/button/__init__.py +27 -0
  44. esphome/components/bl0940/button/calibration_reset_button.cpp +20 -0
  45. esphome/components/bl0940/button/calibration_reset_button.h +19 -0
  46. esphome/components/bl0940/number/__init__.py +94 -0
  47. esphome/components/bl0940/number/calibration_number.cpp +29 -0
  48. esphome/components/bl0940/number/calibration_number.h +26 -0
  49. esphome/components/bl0940/sensor.py +151 -2
  50. esphome/components/bl0942/bl0942.cpp +1 -1
  51. esphome/components/ble_client/output/__init__.py +4 -4
  52. esphome/components/bluetooth_proxy/__init__.py +1 -1
  53. esphome/components/bluetooth_proxy/bluetooth_connection.h +1 -1
  54. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +15 -7
  55. esphome/components/bluetooth_proxy/bluetooth_proxy.h +6 -3
  56. esphome/components/button/__init__.py +2 -2
  57. esphome/components/button/button.cpp +13 -0
  58. esphome/components/button/button.h +4 -7
  59. esphome/components/camera/buffer.h +18 -0
  60. esphome/components/camera/buffer_impl.cpp +20 -0
  61. esphome/components/camera/buffer_impl.h +26 -0
  62. esphome/components/camera/camera.h +43 -0
  63. esphome/components/camera/encoder.h +69 -0
  64. esphome/components/camera_encoder/__init__.py +62 -0
  65. esphome/components/camera_encoder/encoder_buffer_impl.cpp +23 -0
  66. esphome/components/camera_encoder/encoder_buffer_impl.h +25 -0
  67. esphome/components/camera_encoder/esp32_camera_jpeg_encoder.cpp +82 -0
  68. esphome/components/camera_encoder/esp32_camera_jpeg_encoder.h +39 -0
  69. esphome/components/captive_portal/__init__.py +2 -2
  70. esphome/components/captive_portal/captive_index.h +77 -97
  71. esphome/components/captive_portal/captive_portal.cpp +35 -12
  72. esphome/components/captive_portal/captive_portal.h +3 -3
  73. esphome/components/ccs811/ccs811.cpp +3 -3
  74. esphome/components/climate/__init__.py +2 -2
  75. esphome/components/climate/climate.cpp +1 -1
  76. esphome/components/cover/__init__.py +5 -5
  77. esphome/components/cover/cover.cpp +1 -1
  78. esphome/components/cover/cover.h +2 -2
  79. esphome/components/dallas_temp/dallas_temp.cpp +2 -2
  80. esphome/components/datetime/__init__.py +2 -2
  81. esphome/components/datetime/date_entity.h +2 -2
  82. esphome/components/datetime/datetime_entity.h +2 -2
  83. esphome/components/datetime/time_entity.h +2 -2
  84. esphome/components/debug/debug_esp32.cpp +1 -1
  85. esphome/components/display/__init__.py +4 -4
  86. esphome/components/duty_time/duty_time_sensor.cpp +1 -1
  87. esphome/components/esp32/__init__.py +0 -5
  88. esphome/components/esp32/gpio.cpp +27 -23
  89. esphome/components/esp32/gpio.h +26 -11
  90. esphome/components/esp32/preferences.cpp +8 -4
  91. esphome/components/esp32_ble/__init__.py +7 -2
  92. esphome/components/esp32_ble/ble_uuid.cpp +30 -9
  93. esphome/components/esp32_ble_beacon/esp32_ble_beacon.cpp +4 -3
  94. esphome/components/esp32_ble_client/ble_client_base.cpp +7 -3
  95. esphome/components/esp32_ble_client/ble_client_base.h +8 -5
  96. esphome/components/esp32_ble_tracker/__init__.py +2 -2
  97. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +11 -47
  98. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +2 -14
  99. esphome/components/esp8266/__init__.py +2 -2
  100. esphome/components/esp8266/core.cpp +2 -2
  101. esphome/components/esp8266/gpio.py +4 -4
  102. esphome/components/esp8266/preferences.cpp +30 -28
  103. esphome/components/esphome/ota/__init__.py +2 -2
  104. esphome/components/esphome/ota/ota_esphome.cpp +21 -19
  105. esphome/components/esphome/ota/ota_esphome.h +6 -5
  106. esphome/components/ethernet/__init__.py +18 -2
  107. esphome/components/ethernet/ethernet_component.cpp +53 -3
  108. esphome/components/ethernet/ethernet_component.h +4 -0
  109. esphome/components/event/__init__.py +2 -2
  110. esphome/components/event/event.h +4 -4
  111. esphome/components/factory_reset/button/factory_reset_button.cpp +18 -1
  112. esphome/components/factory_reset/button/factory_reset_button.h +6 -1
  113. esphome/components/factory_reset/switch/factory_reset_switch.cpp +18 -1
  114. esphome/components/factory_reset/switch/factory_reset_switch.h +5 -1
  115. esphome/components/fan/__init__.py +2 -2
  116. esphome/components/fan/fan.cpp +2 -1
  117. esphome/components/gdk101/gdk101.cpp +4 -4
  118. esphome/components/globals/__init__.py +2 -2
  119. esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp +19 -18
  120. esphome/components/gpio_expander/cached_gpio.h +36 -16
  121. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.cpp +5 -5
  122. esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +1 -1
  123. esphome/components/haier/haier_base.cpp +1 -1
  124. esphome/components/haier/hon_climate.cpp +1 -1
  125. esphome/components/hlw8012/hlw8012.cpp +5 -5
  126. esphome/components/honeywellabp2_i2c/honeywellabp2.cpp +4 -4
  127. esphome/components/host/preferences.h +3 -2
  128. esphome/components/hte501/hte501.cpp +3 -21
  129. esphome/components/hte501/hte501.h +2 -3
  130. esphome/components/http_request/ota/__init__.py +2 -2
  131. esphome/components/i2c/__init__.py +2 -2
  132. esphome/components/i2c/i2c.cpp +13 -9
  133. esphome/components/i2c/i2c_bus.h +36 -6
  134. esphome/components/i2s_audio/__init__.py +8 -2
  135. esphome/components/i2s_audio/media_player/__init__.py +1 -1
  136. esphome/components/i2s_audio/microphone/__init__.py +1 -1
  137. esphome/components/i2s_audio/speaker/__init__.py +1 -1
  138. esphome/components/ina2xx_base/__init__.py +4 -2
  139. esphome/components/inkplate/__init__.py +1 -0
  140. esphome/components/inkplate/const.py +105 -0
  141. esphome/components/inkplate/display.py +238 -0
  142. esphome/components/{inkplate6 → inkplate}/inkplate.cpp +156 -74
  143. esphome/components/{inkplate6 → inkplate}/inkplate.h +28 -68
  144. esphome/components/inkplate6/__init__.py +0 -1
  145. esphome/components/inkplate6/display.py +2 -211
  146. esphome/components/integration/integration_sensor.cpp +1 -1
  147. esphome/components/json/__init__.py +2 -2
  148. esphome/components/lc709203f/lc709203f.cpp +4 -17
  149. esphome/components/lc709203f/lc709203f.h +2 -3
  150. esphome/components/ld2420/text_sensor/{text_sensor.cpp → ld2420_text_sensor.cpp} +1 -1
  151. esphome/components/ld2450/ld2450.cpp +1 -1
  152. esphome/components/libretiny/preferences.cpp +13 -5
  153. esphome/components/light/__init__.py +2 -2
  154. esphome/components/light/addressable_light_effect.h +7 -0
  155. esphome/components/light/base_light_effects.h +8 -0
  156. esphome/components/light/light_call.cpp +22 -20
  157. esphome/components/light/light_effect.cpp +36 -0
  158. esphome/components/light/light_effect.h +14 -0
  159. esphome/components/light/light_json_schema.cpp +9 -1
  160. esphome/components/light/light_state.cpp +2 -2
  161. esphome/components/light/light_state.h +38 -0
  162. esphome/components/lock/__init__.py +2 -2
  163. esphome/components/lock/lock.h +2 -2
  164. esphome/components/logger/__init__.py +2 -2
  165. esphome/components/logger/logger.cpp +25 -4
  166. esphome/components/logger/logger.h +1 -1
  167. esphome/components/logger/logger_esp32.cpp +16 -8
  168. esphome/components/logger/logger_esp8266.cpp +11 -3
  169. esphome/components/logger/logger_libretiny.cpp +13 -3
  170. esphome/components/logger/logger_rp2040.cpp +14 -3
  171. esphome/components/logger/logger_zephyr.cpp +15 -4
  172. esphome/components/lvgl/defines.py +1 -0
  173. esphome/components/lvgl/hello_world.py +96 -33
  174. esphome/components/lvgl/number/lvgl_number.h +1 -1
  175. esphome/components/lvgl/select/lvgl_select.h +1 -1
  176. esphome/components/lvgl/widgets/__init__.py +0 -1
  177. esphome/components/lvgl/widgets/spinbox.py +20 -11
  178. esphome/components/m5stack_8angle/binary_sensor/m5stack_8angle_binary_sensor.cpp +1 -1
  179. esphome/components/m5stack_8angle/sensor/m5stack_8angle_sensor.cpp +1 -1
  180. esphome/components/mapping/__init__.py +13 -5
  181. esphome/components/mapping/mapping.h +69 -0
  182. esphome/components/max17043/max17043.cpp +2 -2
  183. esphome/components/mcp23016/__init__.py +1 -0
  184. esphome/components/mcp23016/mcp23016.cpp +20 -5
  185. esphome/components/mcp23016/mcp23016.h +10 -4
  186. esphome/components/mcp23x08_base/mcp23x08_base.cpp +1 -1
  187. esphome/components/mcp23x17_base/mcp23x17_base.cpp +2 -2
  188. esphome/components/md5/md5.cpp +3 -2
  189. esphome/components/mdns/__init__.py +2 -2
  190. esphome/components/mdns/mdns_component.cpp +145 -54
  191. esphome/components/media_player/__init__.py +2 -2
  192. esphome/components/micro_wake_word/__init__.py +2 -2
  193. esphome/components/microphone/__init__.py +2 -2
  194. esphome/components/mipi/__init__.py +77 -33
  195. esphome/components/mipi_rgb/__init__.py +2 -0
  196. esphome/components/mipi_rgb/display.py +321 -0
  197. esphome/components/mipi_rgb/mipi_rgb.cpp +388 -0
  198. esphome/components/mipi_rgb/mipi_rgb.h +127 -0
  199. esphome/components/mipi_rgb/models/guition.py +24 -0
  200. esphome/components/mipi_rgb/models/lilygo.py +228 -0
  201. esphome/components/mipi_rgb/models/rpi.py +9 -0
  202. esphome/components/mipi_rgb/models/st7701s.py +214 -0
  203. esphome/components/mipi_rgb/models/waveshare.py +64 -0
  204. esphome/components/mipi_spi/models/jc.py +229 -0
  205. esphome/components/mlx90614/mlx90614.cpp +1 -16
  206. esphome/components/mlx90614/mlx90614.h +0 -1
  207. esphome/components/mqtt/__init__.py +2 -2
  208. esphome/components/mqtt/mqtt_client.cpp +1 -1
  209. esphome/components/mqtt/mqtt_sensor.cpp +7 -2
  210. esphome/components/ms5611/ms5611.cpp +7 -6
  211. esphome/components/network/__init__.py +2 -2
  212. esphome/components/nextion/nextion_upload.cpp +4 -1
  213. esphome/components/nrf52/__init__.py +49 -6
  214. esphome/components/nrf52/const.py +1 -0
  215. esphome/components/nrf52/dfu.cpp +51 -0
  216. esphome/components/nrf52/dfu.h +24 -0
  217. esphome/components/ntc/ntc.cpp +1 -1
  218. esphome/components/number/__init__.py +2 -2
  219. esphome/components/number/automation.cpp +1 -1
  220. esphome/components/number/number.cpp +21 -0
  221. esphome/components/number/number.h +4 -13
  222. esphome/components/opentherm/hub.h +6 -6
  223. esphome/components/opentherm/number/{number.cpp → opentherm_number.cpp} +2 -2
  224. esphome/components/opentherm/output/{output.cpp → opentherm_output.cpp} +1 -1
  225. esphome/components/opentherm/switch/{switch.cpp → opentherm_switch.cpp} +1 -1
  226. esphome/components/openthread/openthread.cpp +41 -7
  227. esphome/components/openthread/openthread.h +11 -0
  228. esphome/components/ota/__init__.py +2 -2
  229. esphome/components/pca6416a/__init__.py +1 -0
  230. esphome/components/pca6416a/pca6416a.cpp +20 -5
  231. esphome/components/pca6416a/pca6416a.h +12 -5
  232. esphome/components/pca9554/__init__.py +2 -1
  233. esphome/components/pca9554/pca9554.cpp +12 -18
  234. esphome/components/pca9554/pca9554.h +10 -9
  235. esphome/components/pcf8574/__init__.py +1 -0
  236. esphome/components/pcf8574/pcf8574.cpp +14 -5
  237. esphome/components/pcf8574/pcf8574.h +13 -6
  238. esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +7 -7
  239. esphome/components/pipsolar/__init__.py +3 -3
  240. esphome/components/pipsolar/output/__init__.py +4 -4
  241. esphome/components/pulse_width/pulse_width.cpp +2 -2
  242. esphome/components/qmp6988/qmp6988.cpp +81 -126
  243. esphome/components/qmp6988/qmp6988.h +31 -37
  244. esphome/components/radon_eye_ble/__init__.py +2 -2
  245. esphome/components/remote_base/__init__.py +6 -8
  246. esphome/components/rotary_encoder/rotary_encoder.cpp +1 -1
  247. esphome/components/rp2040/__init__.py +2 -2
  248. esphome/components/runtime_stats/runtime_stats.cpp +10 -23
  249. esphome/components/runtime_stats/runtime_stats.h +4 -10
  250. esphome/components/safe_mode/__init__.py +2 -2
  251. esphome/components/safe_mode/safe_mode.cpp +33 -31
  252. esphome/components/script/script.cpp +6 -0
  253. esphome/components/script/script.h +19 -5
  254. esphome/components/sdm_meter/sensor.py +3 -1
  255. esphome/components/select/__init__.py +2 -2
  256. esphome/components/select/select.cpp +3 -3
  257. esphome/components/select/select.h +2 -2
  258. esphome/components/select/select_call.cpp +1 -1
  259. esphome/components/sen5x/sen5x.cpp +57 -55
  260. esphome/components/sen5x/sen5x.h +21 -15
  261. esphome/components/sen5x/sensor.py +67 -44
  262. esphome/components/sensirion_common/i2c_sensirion.cpp +18 -47
  263. esphome/components/sensirion_common/i2c_sensirion.h +39 -55
  264. esphome/components/sensor/__init__.py +2 -2
  265. esphome/components/sensor/automation.h +1 -1
  266. esphome/components/sensor/sensor.cpp +34 -6
  267. esphome/components/sensor/sensor.h +4 -21
  268. esphome/components/sgp30/sgp30.cpp +34 -35
  269. esphome/components/sgp30/sgp30.h +11 -10
  270. esphome/components/sgp4x/sgp4x.cpp +2 -2
  271. esphome/components/shelly_dimmer/light.py +7 -7
  272. esphome/components/sht4x/sht4x.cpp +1 -1
  273. esphome/components/sntp/sntp_component.cpp +36 -9
  274. esphome/components/sntp/sntp_component.h +7 -0
  275. esphome/components/sound_level/sound_level.cpp +1 -1
  276. esphome/components/speaker/__init__.py +2 -2
  277. esphome/components/speaker/media_player/__init__.py +2 -2
  278. esphome/components/speaker/media_player/speaker_media_player.cpp +1 -1
  279. esphome/components/spi/__init__.py +2 -2
  280. esphome/components/sprinkler/sprinkler.cpp +1 -1
  281. esphome/components/sps30/sps30.cpp +18 -23
  282. esphome/components/sps30/sps30.h +3 -3
  283. esphome/components/status_led/__init__.py +2 -2
  284. esphome/components/stepper/__init__.py +2 -2
  285. esphome/components/switch/__init__.py +2 -2
  286. esphome/components/switch/switch.cpp +5 -5
  287. esphome/components/sx1509/__init__.py +1 -1
  288. esphome/components/sx1509/sx1509.cpp +12 -7
  289. esphome/components/sx1509/sx1509.h +11 -4
  290. esphome/components/tca9555/tca9555.cpp +5 -5
  291. esphome/components/tee501/tee501.cpp +2 -21
  292. esphome/components/tee501/tee501.h +2 -4
  293. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +1 -1
  294. esphome/components/template/datetime/template_date.cpp +1 -1
  295. esphome/components/template/datetime/template_datetime.cpp +2 -2
  296. esphome/components/template/datetime/template_time.cpp +1 -1
  297. esphome/components/template/number/template_number.cpp +1 -1
  298. esphome/components/template/select/template_select.cpp +1 -1
  299. esphome/components/template/text/template_text.cpp +1 -1
  300. esphome/components/text/__init__.py +2 -2
  301. esphome/components/text/text.h +2 -2
  302. esphome/components/text_sensor/__init__.py +2 -2
  303. esphome/components/text_sensor/text_sensor.h +4 -4
  304. esphome/components/thermostat/climate.py +11 -7
  305. esphome/components/thermostat/thermostat_climate.cpp +237 -206
  306. esphome/components/thermostat/thermostat_climate.h +52 -41
  307. esphome/components/time/__init__.py +2 -2
  308. esphome/components/tmp1075/tmp1075.cpp +1 -1
  309. esphome/components/total_daily_energy/total_daily_energy.cpp +1 -1
  310. esphome/components/touchscreen/__init__.py +2 -2
  311. esphome/components/tuya/number/tuya_number.cpp +1 -1
  312. esphome/components/udp/udp_component.cpp +3 -3
  313. esphome/components/ufire_ec/ufire_ec.cpp +4 -4
  314. esphome/components/ufire_ise/ufire_ise.cpp +4 -4
  315. esphome/components/update/__init__.py +2 -2
  316. esphome/components/usb_uart/usb_uart.cpp +1 -1
  317. esphome/components/valve/__init__.py +5 -5
  318. esphome/components/valve/valve.cpp +1 -1
  319. esphome/components/valve/valve.h +2 -2
  320. esphome/components/wake_on_lan/wake_on_lan.cpp +2 -2
  321. esphome/components/waveshare_epaper/waveshare_213v3.cpp +1 -1
  322. esphome/components/web_server/__init__.py +2 -2
  323. esphome/components/web_server/ota/__init__.py +2 -2
  324. esphome/components/web_server/ota/ota_web_server.cpp +11 -0
  325. esphome/components/web_server/server_index_v2.h +149 -149
  326. esphome/components/web_server/web_server.cpp +58 -12
  327. esphome/components/web_server_base/__init__.py +2 -2
  328. esphome/components/wifi/__init__.py +5 -5
  329. esphome/components/wifi/wifi_component.cpp +4 -4
  330. esphome/components/wifi/wifi_component_esp_idf.cpp +2 -0
  331. esphome/components/wifi_info/wifi_info_text_sensor.h +3 -2
  332. esphome/config_validation.py +2 -2
  333. esphome/const.py +3 -1
  334. esphome/core/__init__.py +1 -0
  335. esphome/core/application.cpp +89 -51
  336. esphome/core/application.h +1 -0
  337. esphome/core/component.cpp +41 -19
  338. esphome/core/component.h +17 -13
  339. esphome/core/config.py +7 -7
  340. esphome/core/defines.h +5 -0
  341. esphome/core/entity_base.cpp +22 -8
  342. esphome/core/entity_base.h +43 -0
  343. esphome/core/helpers.cpp +34 -20
  344. esphome/core/helpers.h +33 -3
  345. esphome/core/ring_buffer.cpp +6 -2
  346. esphome/core/ring_buffer.h +2 -1
  347. esphome/core/scheduler.cpp +178 -97
  348. esphome/core/scheduler.h +67 -36
  349. esphome/core/time.cpp +6 -20
  350. esphome/coroutine.py +80 -3
  351. esphome/cpp_generator.py +13 -0
  352. esphome/cpp_helpers.py +2 -2
  353. esphome/dashboard/web_server.py +69 -15
  354. esphome/espota2.py +13 -6
  355. esphome/helpers.py +68 -83
  356. esphome/resolver.py +67 -0
  357. esphome/util.py +9 -6
  358. esphome/wizard.py +81 -34
  359. esphome/writer.py +13 -0
  360. {esphome-2025.8.4.dist-info → esphome-2025.9.0.dist-info}/METADATA +9 -9
  361. {esphome-2025.8.4.dist-info → esphome-2025.9.0.dist-info}/RECORD +369 -338
  362. /esphome/components/ld2420/text_sensor/{text_sensor.h → ld2420_text_sensor.h} +0 -0
  363. /esphome/components/opentherm/number/{number.h → opentherm_number.h} +0 -0
  364. /esphome/components/opentherm/output/{output.h → opentherm_output.h} +0 -0
  365. /esphome/components/opentherm/switch/{switch.h → opentherm_switch.h} +0 -0
  366. {esphome-2025.8.4.dist-info → esphome-2025.9.0.dist-info}/WHEEL +0 -0
  367. {esphome-2025.8.4.dist-info → esphome-2025.9.0.dist-info}/entry_points.txt +0 -0
  368. {esphome-2025.8.4.dist-info → esphome-2025.9.0.dist-info}/licenses/LICENSE +0 -0
  369. {esphome-2025.8.4.dist-info → esphome-2025.9.0.dist-info}/top_level.txt +0 -0
@@ -1,214 +1,5 @@
1
- from esphome import pins
2
- import esphome.codegen as cg
3
- from esphome.components import display, i2c
4
- from esphome.components.esp32 import CONF_CPU_FREQUENCY
5
1
  import esphome.config_validation as cv
6
- from esphome.const import (
7
- CONF_FULL_UPDATE_EVERY,
8
- CONF_ID,
9
- CONF_LAMBDA,
10
- CONF_MIRROR_X,
11
- CONF_MIRROR_Y,
12
- CONF_MODEL,
13
- CONF_OE_PIN,
14
- CONF_PAGES,
15
- CONF_TRANSFORM,
16
- CONF_WAKEUP_PIN,
17
- PLATFORM_ESP32,
18
- )
19
- import esphome.final_validate as fv
20
-
21
- DEPENDENCIES = ["i2c", "esp32"]
22
- AUTO_LOAD = ["psram"]
23
-
24
- CONF_DISPLAY_DATA_0_PIN = "display_data_0_pin"
25
- CONF_DISPLAY_DATA_1_PIN = "display_data_1_pin"
26
- CONF_DISPLAY_DATA_2_PIN = "display_data_2_pin"
27
- CONF_DISPLAY_DATA_3_PIN = "display_data_3_pin"
28
- CONF_DISPLAY_DATA_4_PIN = "display_data_4_pin"
29
- CONF_DISPLAY_DATA_5_PIN = "display_data_5_pin"
30
- CONF_DISPLAY_DATA_6_PIN = "display_data_6_pin"
31
- CONF_DISPLAY_DATA_7_PIN = "display_data_7_pin"
32
-
33
- CONF_CL_PIN = "cl_pin"
34
- CONF_CKV_PIN = "ckv_pin"
35
- CONF_GREYSCALE = "greyscale"
36
- CONF_GMOD_PIN = "gmod_pin"
37
- CONF_GPIO0_ENABLE_PIN = "gpio0_enable_pin"
38
- CONF_LE_PIN = "le_pin"
39
- CONF_PARTIAL_UPDATING = "partial_updating"
40
- CONF_POWERUP_PIN = "powerup_pin"
41
- CONF_SPH_PIN = "sph_pin"
42
- CONF_SPV_PIN = "spv_pin"
43
- CONF_VCOM_PIN = "vcom_pin"
44
-
45
- inkplate6_ns = cg.esphome_ns.namespace("inkplate6")
46
- Inkplate6 = inkplate6_ns.class_(
47
- "Inkplate6",
48
- cg.PollingComponent,
49
- i2c.I2CDevice,
50
- display.Display,
51
- display.DisplayBuffer,
52
- )
53
-
54
- InkplateModel = inkplate6_ns.enum("InkplateModel")
55
-
56
- MODELS = {
57
- "inkplate_6": InkplateModel.INKPLATE_6,
58
- "inkplate_10": InkplateModel.INKPLATE_10,
59
- "inkplate_6_plus": InkplateModel.INKPLATE_6_PLUS,
60
- "inkplate_6_v2": InkplateModel.INKPLATE_6_V2,
61
- "inkplate_5": InkplateModel.INKPLATE_5,
62
- "inkplate_5_v2": InkplateModel.INKPLATE_5_V2,
63
- }
64
2
 
65
- CONFIG_SCHEMA = cv.All(
66
- display.FULL_DISPLAY_SCHEMA.extend(
67
- {
68
- cv.GenerateID(): cv.declare_id(Inkplate6),
69
- cv.Optional(CONF_GREYSCALE, default=False): cv.boolean,
70
- cv.Optional(CONF_TRANSFORM): cv.Schema(
71
- {
72
- cv.Optional(CONF_MIRROR_X, default=False): cv.boolean,
73
- cv.Optional(CONF_MIRROR_Y, default=False): cv.boolean,
74
- }
75
- ),
76
- cv.Optional(CONF_PARTIAL_UPDATING, default=True): cv.boolean,
77
- cv.Optional(CONF_FULL_UPDATE_EVERY, default=10): cv.uint32_t,
78
- cv.Optional(CONF_MODEL, default="inkplate_6"): cv.enum(
79
- MODELS, lower=True, space="_"
80
- ),
81
- # Control pins
82
- cv.Required(CONF_CKV_PIN): pins.gpio_output_pin_schema,
83
- cv.Required(CONF_GMOD_PIN): pins.gpio_output_pin_schema,
84
- cv.Required(CONF_GPIO0_ENABLE_PIN): pins.gpio_output_pin_schema,
85
- cv.Required(CONF_OE_PIN): pins.gpio_output_pin_schema,
86
- cv.Required(CONF_POWERUP_PIN): pins.gpio_output_pin_schema,
87
- cv.Required(CONF_SPH_PIN): pins.gpio_output_pin_schema,
88
- cv.Required(CONF_SPV_PIN): pins.gpio_output_pin_schema,
89
- cv.Required(CONF_VCOM_PIN): pins.gpio_output_pin_schema,
90
- cv.Required(CONF_WAKEUP_PIN): pins.gpio_output_pin_schema,
91
- cv.Optional(CONF_CL_PIN, default=0): pins.internal_gpio_output_pin_schema,
92
- cv.Optional(CONF_LE_PIN, default=2): pins.internal_gpio_output_pin_schema,
93
- # Data pins
94
- cv.Optional(
95
- CONF_DISPLAY_DATA_0_PIN, default=4
96
- ): pins.internal_gpio_output_pin_schema,
97
- cv.Optional(
98
- CONF_DISPLAY_DATA_1_PIN, default=5
99
- ): pins.internal_gpio_output_pin_schema,
100
- cv.Optional(
101
- CONF_DISPLAY_DATA_2_PIN, default=18
102
- ): pins.internal_gpio_output_pin_schema,
103
- cv.Optional(
104
- CONF_DISPLAY_DATA_3_PIN, default=19
105
- ): pins.internal_gpio_output_pin_schema,
106
- cv.Optional(
107
- CONF_DISPLAY_DATA_4_PIN, default=23
108
- ): pins.internal_gpio_output_pin_schema,
109
- cv.Optional(
110
- CONF_DISPLAY_DATA_5_PIN, default=25
111
- ): pins.internal_gpio_output_pin_schema,
112
- cv.Optional(
113
- CONF_DISPLAY_DATA_6_PIN, default=26
114
- ): pins.internal_gpio_output_pin_schema,
115
- cv.Optional(
116
- CONF_DISPLAY_DATA_7_PIN, default=27
117
- ): pins.internal_gpio_output_pin_schema,
118
- }
119
- )
120
- .extend(cv.polling_component_schema("5s"))
121
- .extend(i2c.i2c_device_schema(0x48)),
122
- cv.has_at_most_one_key(CONF_PAGES, CONF_LAMBDA),
3
+ CONFIG_SCHEMA = cv.invalid(
4
+ "The inkplate6 display component has been renamed to inkplate."
123
5
  )
124
-
125
-
126
- def _validate_cpu_frequency(config):
127
- esp32_config = fv.full_config.get()[PLATFORM_ESP32]
128
- if esp32_config[CONF_CPU_FREQUENCY] != "240MHZ":
129
- raise cv.Invalid(
130
- "Inkplate requires 240MHz CPU frequency (set in esp32 component)"
131
- )
132
- return config
133
-
134
-
135
- FINAL_VALIDATE_SCHEMA = _validate_cpu_frequency
136
-
137
-
138
- async def to_code(config):
139
- var = cg.new_Pvariable(config[CONF_ID])
140
-
141
- await display.register_display(var, config)
142
- await i2c.register_i2c_device(var, config)
143
-
144
- if CONF_LAMBDA in config:
145
- lambda_ = await cg.process_lambda(
146
- config[CONF_LAMBDA], [(display.DisplayRef, "it")], return_type=cg.void
147
- )
148
- cg.add(var.set_writer(lambda_))
149
-
150
- cg.add(var.set_greyscale(config[CONF_GREYSCALE]))
151
- if transform := config.get(CONF_TRANSFORM):
152
- cg.add(var.set_mirror_x(transform[CONF_MIRROR_X]))
153
- cg.add(var.set_mirror_y(transform[CONF_MIRROR_Y]))
154
- cg.add(var.set_partial_updating(config[CONF_PARTIAL_UPDATING]))
155
- cg.add(var.set_full_update_every(config[CONF_FULL_UPDATE_EVERY]))
156
-
157
- cg.add(var.set_model(config[CONF_MODEL]))
158
-
159
- ckv = await cg.gpio_pin_expression(config[CONF_CKV_PIN])
160
- cg.add(var.set_ckv_pin(ckv))
161
-
162
- gmod = await cg.gpio_pin_expression(config[CONF_GMOD_PIN])
163
- cg.add(var.set_gmod_pin(gmod))
164
-
165
- gpio0_enable = await cg.gpio_pin_expression(config[CONF_GPIO0_ENABLE_PIN])
166
- cg.add(var.set_gpio0_enable_pin(gpio0_enable))
167
-
168
- oe = await cg.gpio_pin_expression(config[CONF_OE_PIN])
169
- cg.add(var.set_oe_pin(oe))
170
-
171
- powerup = await cg.gpio_pin_expression(config[CONF_POWERUP_PIN])
172
- cg.add(var.set_powerup_pin(powerup))
173
-
174
- sph = await cg.gpio_pin_expression(config[CONF_SPH_PIN])
175
- cg.add(var.set_sph_pin(sph))
176
-
177
- spv = await cg.gpio_pin_expression(config[CONF_SPV_PIN])
178
- cg.add(var.set_spv_pin(spv))
179
-
180
- vcom = await cg.gpio_pin_expression(config[CONF_VCOM_PIN])
181
- cg.add(var.set_vcom_pin(vcom))
182
-
183
- wakeup = await cg.gpio_pin_expression(config[CONF_WAKEUP_PIN])
184
- cg.add(var.set_wakeup_pin(wakeup))
185
-
186
- cl = await cg.gpio_pin_expression(config[CONF_CL_PIN])
187
- cg.add(var.set_cl_pin(cl))
188
-
189
- le = await cg.gpio_pin_expression(config[CONF_LE_PIN])
190
- cg.add(var.set_le_pin(le))
191
-
192
- display_data_0 = await cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_0_PIN])
193
- cg.add(var.set_display_data_0_pin(display_data_0))
194
-
195
- display_data_1 = await cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_1_PIN])
196
- cg.add(var.set_display_data_1_pin(display_data_1))
197
-
198
- display_data_2 = await cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_2_PIN])
199
- cg.add(var.set_display_data_2_pin(display_data_2))
200
-
201
- display_data_3 = await cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_3_PIN])
202
- cg.add(var.set_display_data_3_pin(display_data_3))
203
-
204
- display_data_4 = await cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_4_PIN])
205
- cg.add(var.set_display_data_4_pin(display_data_4))
206
-
207
- display_data_5 = await cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_5_PIN])
208
- cg.add(var.set_display_data_5_pin(display_data_5))
209
-
210
- display_data_6 = await cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_6_PIN])
211
- cg.add(var.set_display_data_6_pin(display_data_6))
212
-
213
- display_data_7 = await cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_7_PIN])
214
- cg.add(var.set_display_data_7_pin(display_data_7))
@@ -10,7 +10,7 @@ static const char *const TAG = "integration";
10
10
 
11
11
  void IntegrationSensor::setup() {
12
12
  if (this->restore_) {
13
- this->pref_ = global_preferences->make_preference<float>(this->get_object_id_hash());
13
+ this->pref_ = global_preferences->make_preference<float>(this->get_preference_hash());
14
14
  float preference_value = 0;
15
15
  this->pref_.load(&preference_value);
16
16
  this->result_ = preference_value;
@@ -1,6 +1,6 @@
1
1
  import esphome.codegen as cg
2
2
  import esphome.config_validation as cv
3
- from esphome.core import coroutine_with_priority
3
+ from esphome.core import CoroPriority, coroutine_with_priority
4
4
 
5
5
  CODEOWNERS = ["@esphome/core"]
6
6
  json_ns = cg.esphome_ns.namespace("json")
@@ -10,7 +10,7 @@ CONFIG_SCHEMA = cv.All(
10
10
  )
11
11
 
12
12
 
13
- @coroutine_with_priority(1.0)
13
+ @coroutine_with_priority(CoroPriority.BUS)
14
14
  async def to_code(config):
15
15
  cg.add_library("bblanchon/ArduinoJson", "7.4.2")
16
16
  cg.add_define("USE_JSON")
@@ -1,5 +1,6 @@
1
- #include "esphome/core/log.h"
2
1
  #include "lc709203f.h"
2
+ #include "esphome/core/helpers.h"
3
+ #include "esphome/core/log.h"
3
4
 
4
5
  namespace esphome {
5
6
  namespace lc709203f {
@@ -189,7 +190,7 @@ uint8_t Lc709203f::get_register_(uint8_t register_to_read, uint16_t *register_va
189
190
  // Error on the i2c bus
190
191
  this->status_set_warning(
191
192
  str_sprintf("Error code %d when reading from register 0x%02X", return_code, register_to_read).c_str());
192
- } else if (this->crc8_(read_buffer, 5) != read_buffer[5]) {
193
+ } else if (crc8(read_buffer, 5, 0x00, 0x07, true) != read_buffer[5]) {
193
194
  // I2C indicated OK, but the CRC of the data does not matcth.
194
195
  this->status_set_warning(str_sprintf("CRC error reading from register 0x%02X", register_to_read).c_str());
195
196
  } else {
@@ -220,7 +221,7 @@ uint8_t Lc709203f::set_register_(uint8_t register_to_set, uint16_t value_to_set)
220
221
  write_buffer[1] = register_to_set;
221
222
  write_buffer[2] = value_to_set & 0xFF; // Low byte
222
223
  write_buffer[3] = (value_to_set >> 8) & 0xFF; // High byte
223
- write_buffer[4] = this->crc8_(write_buffer, 4);
224
+ write_buffer[4] = crc8(write_buffer, 4, 0x00, 0x07, true);
224
225
 
225
226
  for (uint8_t i = 0; i <= LC709203F_I2C_RETRY_COUNT; i++) {
226
227
  // Note: we don't write the first byte of the write buffer to the device.
@@ -239,20 +240,6 @@ uint8_t Lc709203f::set_register_(uint8_t register_to_set, uint16_t value_to_set)
239
240
  return return_code;
240
241
  }
241
242
 
242
- uint8_t Lc709203f::crc8_(uint8_t *byte_buffer, uint8_t length_of_crc) {
243
- uint8_t crc = 0x00;
244
- const uint8_t polynomial(0x07);
245
-
246
- for (uint8_t j = length_of_crc; j; --j) {
247
- crc ^= *byte_buffer++;
248
-
249
- for (uint8_t i = 8; i; --i) {
250
- crc = (crc & 0x80) ? (crc << 1) ^ polynomial : (crc << 1);
251
- }
252
- }
253
- return crc;
254
- }
255
-
256
243
  void Lc709203f::set_pack_size(uint16_t pack_size) {
257
244
  static const uint16_t PACK_SIZE_ARRAY[6] = {100, 200, 500, 1000, 2000, 3000};
258
245
  static const uint16_t APA_ARRAY[6] = {0x08, 0x0B, 0x10, 0x19, 0x2D, 0x36};
@@ -1,8 +1,8 @@
1
1
  #pragma once
2
2
 
3
- #include "esphome/core/component.h"
4
- #include "esphome/components/sensor/sensor.h"
5
3
  #include "esphome/components/i2c/i2c.h"
4
+ #include "esphome/components/sensor/sensor.h"
5
+ #include "esphome/core/component.h"
6
6
 
7
7
  namespace esphome {
8
8
  namespace lc709203f {
@@ -38,7 +38,6 @@ class Lc709203f : public sensor::Sensor, public PollingComponent, public i2c::I2
38
38
  private:
39
39
  uint8_t get_register_(uint8_t register_to_read, uint16_t *register_value);
40
40
  uint8_t set_register_(uint8_t register_to_set, uint16_t value_to_set);
41
- uint8_t crc8_(uint8_t *byte_buffer, uint8_t length_of_crc);
42
41
 
43
42
  protected:
44
43
  sensor::Sensor *voltage_sensor_{nullptr};
@@ -1,4 +1,4 @@
1
- #include "text_sensor.h"
1
+ #include "ld2420_text_sensor.h"
2
2
  #include "esphome/core/helpers.h"
3
3
  #include "esphome/core/log.h"
4
4
 
@@ -184,7 +184,7 @@ static inline bool validate_header_footer(const uint8_t *header_footer, const ui
184
184
  void LD2450Component::setup() {
185
185
  #ifdef USE_NUMBER
186
186
  if (this->presence_timeout_number_ != nullptr) {
187
- this->pref_ = global_preferences->make_preference<float>(this->presence_timeout_number_->get_object_id_hash());
187
+ this->pref_ = global_preferences->make_preference<float>(this->presence_timeout_number_->get_preference_hash());
188
188
  this->set_presence_timeout();
189
189
  }
190
190
  #endif
@@ -5,7 +5,7 @@
5
5
  #include "esphome/core/preferences.h"
6
6
  #include <flashdb.h>
7
7
  #include <cstring>
8
- #include <vector>
8
+ #include <memory>
9
9
  #include <string>
10
10
 
11
11
  namespace esphome {
@@ -139,21 +139,29 @@ class LibreTinyPreferences : public ESPPreferences {
139
139
  }
140
140
 
141
141
  bool is_changed(const fdb_kvdb_t db, const NVSData &to_save) {
142
- NVSData stored_data{};
143
142
  struct fdb_kv kv;
144
143
  fdb_kv_t kvp = fdb_kv_get_obj(db, to_save.key.c_str(), &kv);
145
144
  if (kvp == nullptr) {
146
145
  ESP_LOGV(TAG, "fdb_kv_get_obj('%s'): nullptr - the key might not be set yet", to_save.key.c_str());
147
146
  return true;
148
147
  }
149
- stored_data.data.resize(kv.value_len);
150
- fdb_blob_make(&blob, stored_data.data.data(), kv.value_len);
148
+
149
+ // Check size first - if different, data has changed
150
+ if (kv.value_len != to_save.data.size()) {
151
+ return true;
152
+ }
153
+
154
+ // Allocate buffer on heap to avoid stack allocation for large data
155
+ auto stored_data = std::make_unique<uint8_t[]>(kv.value_len);
156
+ fdb_blob_make(&blob, stored_data.get(), kv.value_len);
151
157
  size_t actual_len = fdb_kv_get_blob(db, to_save.key.c_str(), &blob);
152
158
  if (actual_len != kv.value_len) {
153
159
  ESP_LOGV(TAG, "fdb_kv_get_blob('%s') len mismatch: %u != %u", to_save.key.c_str(), actual_len, kv.value_len);
154
160
  return true;
155
161
  }
156
- return to_save.data != stored_data.data;
162
+
163
+ // Compare the actual data
164
+ return memcmp(to_save.data.data(), stored_data.get(), kv.value_len) != 0;
157
165
  }
158
166
 
159
167
  bool reset() override {
@@ -37,7 +37,7 @@ from esphome.const import (
37
37
  CONF_WEB_SERVER,
38
38
  CONF_WHITE,
39
39
  )
40
- from esphome.core import CORE, coroutine_with_priority
40
+ from esphome.core import CORE, CoroPriority, coroutine_with_priority
41
41
  from esphome.core.entity_helpers import entity_duplicate_validator, setup_entity
42
42
  from esphome.cpp_generator import MockObjClass
43
43
 
@@ -283,6 +283,6 @@ async def new_light(config, *args):
283
283
  return output_var
284
284
 
285
285
 
286
- @coroutine_with_priority(100.0)
286
+ @coroutine_with_priority(CoroPriority.CORE)
287
287
  async def to_code(config):
288
288
  cg.add_global(light_ns.using)
@@ -44,6 +44,13 @@ class AddressableLightEffect : public LightEffect {
44
44
  this->apply(*this->get_addressable_(), current_color);
45
45
  }
46
46
 
47
+ /// Get effect index specifically for addressable effects.
48
+ /// Can be used by effects to modify behavior based on their position in the list.
49
+ uint32_t get_effect_index() const { return this->get_index(); }
50
+
51
+ /// Check if this is the currently running addressable effect.
52
+ bool is_current_effect() const { return this->is_active() && this->get_addressable_()->is_effect_active(); }
53
+
47
54
  protected:
48
55
  AddressableLight *get_addressable_() const { return (AddressableLight *) this->state_->get_output(); }
49
56
  };
@@ -125,6 +125,10 @@ class LambdaLightEffect : public LightEffect {
125
125
  }
126
126
  }
127
127
 
128
+ /// Get the current effect index for use in lambda functions.
129
+ /// This can be useful for lambda effects that need to know their own index.
130
+ uint32_t get_current_index() const { return this->get_index(); }
131
+
128
132
  protected:
129
133
  std::function<void(bool initial_run)> f_;
130
134
  uint32_t update_interval_;
@@ -143,6 +147,10 @@ class AutomationLightEffect : public LightEffect {
143
147
  }
144
148
  Trigger<> *get_trig() const { return trig_; }
145
149
 
150
+ /// Get the current effect index for use in automations.
151
+ /// Useful for automations that need to know which effect is running.
152
+ uint32_t get_current_index() const { return this->get_index(); }
153
+
146
154
  protected:
147
155
  Trigger<> *trig_{new Trigger<>};
148
156
  };
@@ -11,19 +11,21 @@ static const char *const TAG = "light";
11
11
 
12
12
  // Helper functions to reduce code size for logging
13
13
  #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_WARN
14
- static void log_validation_warning(const char *name, const char *param_name, float val, float min, float max) {
15
- ESP_LOGW(TAG, "'%s': %s value %.2f is out of range [%.1f - %.1f]", name, param_name, val, min, max);
14
+ static void log_validation_warning(const char *name, const LogString *param_name, float val, float min, float max) {
15
+ ESP_LOGW(TAG, "'%s': %s value %.2f is out of range [%.1f - %.1f]", name, LOG_STR_ARG(param_name), val, min, max);
16
16
  }
17
17
 
18
- static void log_feature_not_supported(const char *name, const char *feature) {
19
- ESP_LOGW(TAG, "'%s': %s not supported", name, feature);
18
+ static void log_feature_not_supported(const char *name, const LogString *feature) {
19
+ ESP_LOGW(TAG, "'%s': %s not supported", name, LOG_STR_ARG(feature));
20
20
  }
21
21
 
22
- static void log_color_mode_not_supported(const char *name, const char *feature) {
23
- ESP_LOGW(TAG, "'%s': color mode does not support setting %s", name, feature);
22
+ static void log_color_mode_not_supported(const char *name, const LogString *feature) {
23
+ ESP_LOGW(TAG, "'%s': color mode does not support setting %s", name, LOG_STR_ARG(feature));
24
24
  }
25
25
 
26
- static void log_invalid_parameter(const char *name, const char *message) { ESP_LOGW(TAG, "'%s': %s", name, message); }
26
+ static void log_invalid_parameter(const char *name, const LogString *message) {
27
+ ESP_LOGW(TAG, "'%s': %s", name, LOG_STR_ARG(message));
28
+ }
27
29
  #else
28
30
  #define log_validation_warning(name, param_name, val, min, max)
29
31
  #define log_feature_not_supported(name, feature)
@@ -201,19 +203,19 @@ LightColorValues LightCall::validate_() {
201
203
 
202
204
  // Brightness exists check
203
205
  if (this->has_brightness() && this->brightness_ > 0.0f && !(color_mode & ColorCapability::BRIGHTNESS)) {
204
- log_feature_not_supported(name, "brightness");
206
+ log_feature_not_supported(name, LOG_STR("brightness"));
205
207
  this->set_flag_(FLAG_HAS_BRIGHTNESS, false);
206
208
  }
207
209
 
208
210
  // Transition length possible check
209
211
  if (this->has_transition_() && this->transition_length_ != 0 && !(color_mode & ColorCapability::BRIGHTNESS)) {
210
- log_feature_not_supported(name, "transitions");
212
+ log_feature_not_supported(name, LOG_STR("transitions"));
211
213
  this->set_flag_(FLAG_HAS_TRANSITION, false);
212
214
  }
213
215
 
214
216
  // Color brightness exists check
215
217
  if (this->has_color_brightness() && this->color_brightness_ > 0.0f && !(color_mode & ColorCapability::RGB)) {
216
- log_color_mode_not_supported(name, "RGB brightness");
218
+ log_color_mode_not_supported(name, LOG_STR("RGB brightness"));
217
219
  this->set_flag_(FLAG_HAS_COLOR_BRIGHTNESS, false);
218
220
  }
219
221
 
@@ -221,7 +223,7 @@ LightColorValues LightCall::validate_() {
221
223
  if ((this->has_red() && this->red_ > 0.0f) || (this->has_green() && this->green_ > 0.0f) ||
222
224
  (this->has_blue() && this->blue_ > 0.0f)) {
223
225
  if (!(color_mode & ColorCapability::RGB)) {
224
- log_color_mode_not_supported(name, "RGB color");
226
+ log_color_mode_not_supported(name, LOG_STR("RGB color"));
225
227
  this->set_flag_(FLAG_HAS_RED, false);
226
228
  this->set_flag_(FLAG_HAS_GREEN, false);
227
229
  this->set_flag_(FLAG_HAS_BLUE, false);
@@ -231,21 +233,21 @@ LightColorValues LightCall::validate_() {
231
233
  // White value exists check
232
234
  if (this->has_white() && this->white_ > 0.0f &&
233
235
  !(color_mode & ColorCapability::WHITE || color_mode & ColorCapability::COLD_WARM_WHITE)) {
234
- log_color_mode_not_supported(name, "white value");
236
+ log_color_mode_not_supported(name, LOG_STR("white value"));
235
237
  this->set_flag_(FLAG_HAS_WHITE, false);
236
238
  }
237
239
 
238
240
  // Color temperature exists check
239
241
  if (this->has_color_temperature() &&
240
242
  !(color_mode & ColorCapability::COLOR_TEMPERATURE || color_mode & ColorCapability::COLD_WARM_WHITE)) {
241
- log_color_mode_not_supported(name, "color temperature");
243
+ log_color_mode_not_supported(name, LOG_STR("color temperature"));
242
244
  this->set_flag_(FLAG_HAS_COLOR_TEMPERATURE, false);
243
245
  }
244
246
 
245
247
  // Cold/warm white value exists check
246
248
  if ((this->has_cold_white() && this->cold_white_ > 0.0f) || (this->has_warm_white() && this->warm_white_ > 0.0f)) {
247
249
  if (!(color_mode & ColorCapability::COLD_WARM_WHITE)) {
248
- log_color_mode_not_supported(name, "cold/warm white value");
250
+ log_color_mode_not_supported(name, LOG_STR("cold/warm white value"));
249
251
  this->set_flag_(FLAG_HAS_COLD_WHITE, false);
250
252
  this->set_flag_(FLAG_HAS_WARM_WHITE, false);
251
253
  }
@@ -255,7 +257,7 @@ LightColorValues LightCall::validate_() {
255
257
  if (this->has_##name_()) { \
256
258
  auto val = this->name_##_; \
257
259
  if (val < (min) || val > (max)) { \
258
- log_validation_warning(name, LOG_STR_LITERAL(upper_name), val, (min), (max)); \
260
+ log_validation_warning(name, LOG_STR(upper_name), val, (min), (max)); \
259
261
  this->name_##_ = clamp(val, (min), (max)); \
260
262
  } \
261
263
  }
@@ -319,7 +321,7 @@ LightColorValues LightCall::validate_() {
319
321
 
320
322
  // Flash length check
321
323
  if (this->has_flash_() && this->flash_length_ == 0) {
322
- log_invalid_parameter(name, "flash length must be greater than zero");
324
+ log_invalid_parameter(name, LOG_STR("flash length must be greater than zero"));
323
325
  this->set_flag_(FLAG_HAS_FLASH, false);
324
326
  }
325
327
 
@@ -338,13 +340,13 @@ LightColorValues LightCall::validate_() {
338
340
  }
339
341
 
340
342
  if (this->has_effect_() && (this->has_transition_() || this->has_flash_())) {
341
- log_invalid_parameter(name, "effect cannot be used with transition/flash");
343
+ log_invalid_parameter(name, LOG_STR("effect cannot be used with transition/flash"));
342
344
  this->set_flag_(FLAG_HAS_TRANSITION, false);
343
345
  this->set_flag_(FLAG_HAS_FLASH, false);
344
346
  }
345
347
 
346
348
  if (this->has_flash_() && this->has_transition_()) {
347
- log_invalid_parameter(name, "flash cannot be used with transition");
349
+ log_invalid_parameter(name, LOG_STR("flash cannot be used with transition"));
348
350
  this->set_flag_(FLAG_HAS_TRANSITION, false);
349
351
  }
350
352
 
@@ -361,7 +363,7 @@ LightColorValues LightCall::validate_() {
361
363
  }
362
364
 
363
365
  if (this->has_transition_() && !supports_transition) {
364
- log_feature_not_supported(name, "transitions");
366
+ log_feature_not_supported(name, LOG_STR("transitions"));
365
367
  this->set_flag_(FLAG_HAS_TRANSITION, false);
366
368
  }
367
369
 
@@ -371,7 +373,7 @@ LightColorValues LightCall::validate_() {
371
373
  bool target_state = this->has_state() ? this->state_ : v.is_on();
372
374
  if (!this->has_flash_() && !target_state) {
373
375
  if (this->has_effect_()) {
374
- log_invalid_parameter(name, "cannot start effect when turning off");
376
+ log_invalid_parameter(name, LOG_STR("cannot start effect when turning off"));
375
377
  this->set_flag_(FLAG_HAS_EFFECT, false);
376
378
  } else if (this->parent_->active_effect_index_ != 0 && explicit_turn_off_request) {
377
379
  // Auto turn off effect
@@ -0,0 +1,36 @@
1
+ #include "light_effect.h"
2
+ #include "light_state.h"
3
+
4
+ namespace esphome {
5
+ namespace light {
6
+
7
+ uint32_t LightEffect::get_index() const {
8
+ if (this->state_ == nullptr) {
9
+ return 0;
10
+ }
11
+ return this->get_index_in_parent_();
12
+ }
13
+
14
+ bool LightEffect::is_active() const {
15
+ if (this->state_ == nullptr) {
16
+ return false;
17
+ }
18
+ return this->get_index() != 0 && this->state_->get_current_effect_index() == this->get_index();
19
+ }
20
+
21
+ uint32_t LightEffect::get_index_in_parent_() const {
22
+ if (this->state_ == nullptr) {
23
+ return 0;
24
+ }
25
+
26
+ const auto &effects = this->state_->get_effects();
27
+ for (size_t i = 0; i < effects.size(); i++) {
28
+ if (effects[i] == this) {
29
+ return i + 1; // Effects are 1-indexed in the API
30
+ }
31
+ }
32
+ return 0; // Not found
33
+ }
34
+
35
+ } // namespace light
36
+ } // namespace esphome
@@ -34,9 +34,23 @@ class LightEffect {
34
34
  this->init();
35
35
  }
36
36
 
37
+ /// Get the index of this effect in the parent light's effect list.
38
+ /// Returns 0 if not found or not initialized.
39
+ uint32_t get_index() const;
40
+
41
+ /// Check if this effect is currently active.
42
+ bool is_active() const;
43
+
44
+ /// Get a reference to the parent light state.
45
+ /// Returns nullptr if not initialized.
46
+ LightState *get_light_state() const { return this->state_; }
47
+
37
48
  protected:
38
49
  LightState *state_{nullptr};
39
50
  std::string name_;
51
+
52
+ /// Internal method to find this effect's index in the parent light's effect list.
53
+ uint32_t get_index_in_parent_() const;
40
54
  };
41
55
 
42
56
  } // namespace light
@@ -36,8 +36,11 @@ static constexpr const char *get_color_mode_json_str(ColorMode mode) {
36
36
 
37
37
  void LightJSONSchema::dump_json(LightState &state, JsonObject root) {
38
38
  // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
39
- if (state.supports_effects())
39
+ if (state.supports_effects()) {
40
40
  root["effect"] = state.get_effect_name();
41
+ root["effect_index"] = state.get_current_effect_index();
42
+ root["effect_count"] = state.get_effect_count();
43
+ }
41
44
 
42
45
  auto values = state.remote_values;
43
46
  auto traits = state.get_output()->get_traits();
@@ -160,6 +163,11 @@ void LightJSONSchema::parse_json(LightState &state, LightCall &call, JsonObject
160
163
  const char *effect = root["effect"];
161
164
  call.set_effect(effect);
162
165
  }
166
+
167
+ if (root["effect_index"].is<uint32_t>()) {
168
+ uint32_t effect_index = root["effect_index"];
169
+ call.set_effect(effect_index);
170
+ }
163
171
  }
164
172
 
165
173
  } // namespace light
@@ -41,7 +41,7 @@ void LightState::setup() {
41
41
  case LIGHT_RESTORE_DEFAULT_ON:
42
42
  case LIGHT_RESTORE_INVERTED_DEFAULT_OFF:
43
43
  case LIGHT_RESTORE_INVERTED_DEFAULT_ON:
44
- this->rtc_ = global_preferences->make_preference<LightStateRTCState>(this->get_object_id_hash());
44
+ this->rtc_ = global_preferences->make_preference<LightStateRTCState>(this->get_preference_hash());
45
45
  // Attempt to load from preferences, else fall back to default values
46
46
  if (!this->rtc_.load(&recovered)) {
47
47
  recovered.state = (this->restore_mode_ == LIGHT_RESTORE_DEFAULT_ON ||
@@ -54,7 +54,7 @@ void LightState::setup() {
54
54
  break;
55
55
  case LIGHT_RESTORE_AND_OFF:
56
56
  case LIGHT_RESTORE_AND_ON:
57
- this->rtc_ = global_preferences->make_preference<LightStateRTCState>(this->get_object_id_hash());
57
+ this->rtc_ = global_preferences->make_preference<LightStateRTCState>(this->get_preference_hash());
58
58
  this->rtc_.load(&recovered);
59
59
  recovered.state = (this->restore_mode_ == LIGHT_RESTORE_AND_ON);
60
60
  break;