esphome 2025.7.5__py3-none-any.whl → 2025.8.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 (752) hide show
  1. esphome/__main__.py +189 -82
  2. esphome/automation.py +2 -4
  3. esphome/build_gen/__init__.py +0 -0
  4. esphome/build_gen/platformio.py +102 -0
  5. esphome/components/a4988/a4988.cpp +0 -1
  6. esphome/components/absolute_humidity/absolute_humidity.cpp +0 -2
  7. esphome/components/absolute_humidity/sensor.py +2 -2
  8. esphome/components/adc/__init__.py +123 -85
  9. esphome/components/adc/adc_sensor.h +98 -35
  10. esphome/components/adc/adc_sensor_common.cpp +10 -4
  11. esphome/components/adc/adc_sensor_esp32.cpp +291 -123
  12. esphome/components/adc/adc_sensor_esp8266.cpp +1 -4
  13. esphome/components/adc/adc_sensor_libretiny.cpp +1 -2
  14. esphome/components/adc/adc_sensor_rp2040.cpp +1 -2
  15. esphome/components/adc/adc_sensor_zephyr.cpp +207 -0
  16. esphome/components/adc/sensor.py +61 -27
  17. esphome/components/adc128s102/adc128s102.cpp +1 -4
  18. esphome/components/ade7880/sensor.py +75 -49
  19. esphome/components/ads1115/ads1115.cpp +0 -1
  20. esphome/components/ads1118/ads1118.cpp +0 -1
  21. esphome/components/ags10/ags10.cpp +0 -4
  22. esphome/components/aht10/aht10.cpp +0 -4
  23. esphome/components/aic3204/aic3204.cpp +0 -2
  24. esphome/components/airthings_wave_plus/__init__.py +1 -1
  25. esphome/components/airthings_wave_plus/airthings_wave_plus.cpp +22 -4
  26. esphome/components/airthings_wave_plus/airthings_wave_plus.h +10 -1
  27. esphome/components/airthings_wave_plus/sensor.py +55 -28
  28. esphome/components/alarm_control_panel/__init__.py +4 -9
  29. esphome/components/am2315c/am2315c.cpp +0 -2
  30. esphome/components/am2320/am2320.cpp +0 -1
  31. esphome/components/animation/__init__.py +14 -11
  32. esphome/components/apds9306/apds9306.cpp +0 -4
  33. esphome/components/apds9960/apds9960.cpp +0 -1
  34. esphome/components/api/__init__.py +29 -4
  35. esphome/components/api/api_connection.cpp +378 -401
  36. esphome/components/api/api_connection.h +102 -52
  37. esphome/components/api/api_frame_helper.cpp +69 -896
  38. esphome/components/api/api_frame_helper.h +31 -126
  39. esphome/components/api/api_frame_helper_noise.cpp +583 -0
  40. esphome/components/api/api_frame_helper_noise.h +68 -0
  41. esphome/components/api/api_frame_helper_plaintext.cpp +290 -0
  42. esphome/components/api/api_frame_helper_plaintext.h +53 -0
  43. esphome/components/api/api_noise_context.h +2 -4
  44. esphome/components/api/api_pb2.cpp +1601 -1808
  45. esphome/components/api/api_pb2.h +367 -323
  46. esphome/components/api/api_pb2_dump.cpp +1137 -3466
  47. esphome/components/api/api_pb2_includes.h +34 -0
  48. esphome/components/api/api_pb2_service.cpp +94 -105
  49. esphome/components/api/api_pb2_service.h +27 -16
  50. esphome/components/api/api_server.cpp +18 -17
  51. esphome/components/api/api_server.h +8 -5
  52. esphome/components/api/client.py +16 -8
  53. esphome/components/api/custom_api_device.h +68 -14
  54. esphome/components/api/homeassistant_service.h +24 -19
  55. esphome/components/api/list_entities.cpp +3 -5
  56. esphome/components/api/list_entities.h +2 -4
  57. esphome/components/api/proto.cpp +3 -5
  58. esphome/components/api/proto.h +239 -274
  59. esphome/components/api/subscribe_state.cpp +2 -4
  60. esphome/components/api/subscribe_state.h +2 -4
  61. esphome/components/api/user_services.cpp +2 -4
  62. esphome/components/api/user_services.h +8 -8
  63. esphome/components/as3935/as3935.cpp +0 -2
  64. esphome/components/as3935_spi/as3935_spi.cpp +0 -2
  65. esphome/components/as5600/__init__.py +1 -1
  66. esphome/components/as5600/as5600.cpp +0 -2
  67. esphome/components/as5600/sensor/__init__.py +0 -1
  68. esphome/components/as7341/as7341.cpp +0 -1
  69. esphome/components/async_tcp/__init__.py +1 -1
  70. esphome/components/at581x/at581x.cpp +1 -1
  71. esphome/components/atm90e26/atm90e26.cpp +0 -1
  72. esphome/components/atm90e32/atm90e32.cpp +488 -118
  73. esphome/components/atm90e32/atm90e32.h +44 -5
  74. esphome/components/audio/audio.h +2 -2
  75. esphome/components/axs15231/touchscreen/axs15231_touchscreen.cpp +0 -2
  76. esphome/components/beken_spi_led_strip/led_strip.cpp +0 -2
  77. esphome/components/bh1750/bh1750.cpp +0 -1
  78. esphome/components/binary_sensor/__init__.py +14 -12
  79. esphome/components/ble_client/__init__.py +4 -7
  80. esphome/components/bluetooth_proxy/__init__.py +40 -3
  81. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +387 -82
  82. esphome/components/bluetooth_proxy/bluetooth_connection.h +16 -5
  83. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +102 -311
  84. esphome/components/bluetooth_proxy/bluetooth_proxy.h +30 -14
  85. esphome/components/bme280_base/bme280_base.cpp +15 -16
  86. esphome/components/bme680/bme680.cpp +2 -3
  87. esphome/components/bme680_bsec/bme680_bsec.cpp +0 -2
  88. esphome/components/bme68x_bsec2/bme68x_bsec2.cpp +0 -2
  89. esphome/components/bmi160/bmi160.cpp +0 -1
  90. esphome/components/bmp085/bmp085.cpp +0 -1
  91. esphome/components/bmp280_base/bmp280_base.cpp +13 -14
  92. esphome/components/bmp3xx_base/bmp3xx_base.cpp +0 -1
  93. esphome/components/bmp581/bmp581.cpp +0 -2
  94. esphome/components/bp1658cj/bp1658cj.cpp +0 -1
  95. esphome/components/bp5758d/bp5758d.cpp +0 -1
  96. esphome/components/button/__init__.py +0 -1
  97. esphome/components/canbus/__init__.py +2 -3
  98. esphome/components/canbus/canbus.cpp +0 -1
  99. esphome/components/cap1188/cap1188.cpp +0 -2
  100. esphome/components/captive_portal/__init__.py +1 -1
  101. esphome/components/cd74hc4067/cd74hc4067.cpp +0 -2
  102. esphome/components/ch422g/ch422g.cpp +0 -1
  103. esphome/components/chsc6x/chsc6x_touchscreen.cpp +0 -3
  104. esphome/components/climate/__init__.py +0 -1
  105. esphome/components/climate/climate_traits.h +24 -0
  106. esphome/components/cm1106/cm1106.cpp +0 -1
  107. esphome/components/const/__init__.py +6 -0
  108. esphome/components/cover/__init__.py +0 -1
  109. esphome/components/cover/cover.cpp +9 -13
  110. esphome/components/cs5460a/cs5460a.cpp +0 -2
  111. esphome/components/cse7761/cse7761.cpp +0 -1
  112. esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +0 -2
  113. esphome/components/cst816/touchscreen/cst816_touchscreen.cpp +0 -2
  114. esphome/components/dac7678/dac7678_output.cpp +0 -2
  115. esphome/components/dallas_temp/dallas_temp.cpp +0 -1
  116. esphome/components/datetime/__init__.py +0 -2
  117. esphome/components/debug/__init__.py +15 -1
  118. esphome/components/debug/debug_zephyr.cpp +281 -0
  119. esphome/components/debug/sensor.py +2 -1
  120. esphome/components/deep_sleep/deep_sleep_component.cpp +0 -1
  121. esphome/components/deep_sleep/deep_sleep_esp32.cpp +20 -1
  122. esphome/components/dfrobot_sen0395/__init__.py +1 -2
  123. esphome/components/dht/dht.cpp +0 -1
  124. esphome/components/dht12/dht12.cpp +0 -1
  125. esphome/components/display/__init__.py +16 -3
  126. esphome/components/display_menu_base/__init__.py +1 -1
  127. esphome/components/dps310/dps310.cpp +0 -2
  128. esphome/components/ds1307/ds1307.cpp +0 -1
  129. esphome/components/ds2484/ds2484.cpp +0 -1
  130. esphome/components/duty_cycle/duty_cycle_sensor.cpp +0 -1
  131. esphome/components/ee895/ee895.cpp +0 -1
  132. esphome/components/ektf2232/touchscreen/ektf2232.cpp +0 -1
  133. esphome/components/emc2101/emc2101.cpp +0 -2
  134. esphome/components/ens160_base/ens160_base.cpp +0 -2
  135. esphome/components/ens210/ens210.cpp +0 -1
  136. esphome/components/es7210/es7210.cpp +0 -2
  137. esphome/components/es7243e/es7243e.cpp +0 -2
  138. esphome/components/es8156/es8156.cpp +0 -2
  139. esphome/components/es8311/es8311.cpp +0 -2
  140. esphome/components/es8388/es8388.cpp +0 -2
  141. esphome/components/esp32/__init__.py +199 -58
  142. esphome/components/esp32/boards.py +17 -0
  143. esphome/components/esp32/gpio.cpp +0 -1
  144. esphome/components/esp32/gpio.py +1 -2
  145. esphome/components/esp32/gpio_esp32_h2.py +2 -7
  146. esphome/components/esp32/gpio_esp32_p4.py +2 -7
  147. esphome/components/esp32/post_build.py.script +112 -61
  148. esphome/components/esp32_ble/__init__.py +40 -2
  149. esphome/components/esp32_ble/ble.cpp +12 -8
  150. esphome/components/esp32_ble/ble.h +18 -18
  151. esphome/components/esp32_ble/ble_advertising.cpp +5 -5
  152. esphome/components/esp32_ble/ble_advertising.h +7 -5
  153. esphome/components/esp32_ble/ble_event.h +2 -4
  154. esphome/components/esp32_ble/ble_scan_result.h +2 -4
  155. esphome/components/esp32_ble/ble_uuid.cpp +5 -5
  156. esphome/components/esp32_ble/ble_uuid.h +6 -5
  157. esphome/components/esp32_ble_beacon/__init__.py +4 -0
  158. esphome/components/esp32_ble_client/__init__.py +1 -1
  159. esphome/components/esp32_ble_client/ble_characteristic.cpp +4 -4
  160. esphome/components/esp32_ble_client/ble_characteristic.h +6 -4
  161. esphome/components/esp32_ble_client/ble_client_base.cpp +155 -104
  162. esphome/components/esp32_ble_client/ble_client_base.h +17 -6
  163. esphome/components/esp32_ble_client/ble_descriptor.h +6 -4
  164. esphome/components/esp32_ble_client/ble_service.cpp +4 -4
  165. esphome/components/esp32_ble_client/ble_service.h +6 -4
  166. esphome/components/esp32_ble_server/__init__.py +15 -12
  167. esphome/components/esp32_ble_tracker/__init__.py +79 -11
  168. esphome/components/esp32_ble_tracker/automation.h +4 -4
  169. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +264 -261
  170. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +103 -37
  171. esphome/components/esp32_camera/__init__.py +13 -1
  172. esphome/components/esp32_camera/esp32_camera.cpp +7 -2
  173. esphome/components/esp32_camera/esp32_camera.h +1 -0
  174. esphome/components/esp32_dac/esp32_dac.cpp +3 -19
  175. esphome/components/esp32_dac/esp32_dac.h +4 -8
  176. esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -6
  177. esphome/components/esp32_rmt_led_strip/light.py +1 -1
  178. esphome/components/esp32_touch/__init__.py +2 -3
  179. esphome/components/esp32_touch/esp32_touch.h +9 -6
  180. esphome/components/esp32_touch/esp32_touch_common.cpp +2 -0
  181. esphome/components/esp32_touch/esp32_touch_v1.cpp +7 -9
  182. esphome/components/esp32_touch/esp32_touch_v2.cpp +10 -6
  183. esphome/components/esp8266/__init__.py +3 -1
  184. esphome/components/esp8266_pwm/esp8266_pwm.cpp +0 -1
  185. esphome/components/esphome/ota/__init__.py +1 -2
  186. esphome/components/esphome/ota/ota_esphome.cpp +150 -77
  187. esphome/components/esphome/ota/ota_esphome.h +8 -1
  188. esphome/components/espnow/__init__.py +309 -0
  189. esphome/components/espnow/automation.h +175 -0
  190. esphome/components/espnow/espnow_component.cpp +468 -0
  191. esphome/components/espnow/espnow_component.h +183 -0
  192. esphome/components/espnow/espnow_err.h +19 -0
  193. esphome/components/espnow/espnow_packet.h +166 -0
  194. esphome/components/ethernet/__init__.py +7 -1
  195. esphome/components/ethernet/esp_eth_phy_jl1101.c +5 -0
  196. esphome/components/ethernet/ethernet_component.cpp +0 -1
  197. esphome/components/ethernet/ethernet_component.h +4 -0
  198. esphome/components/ethernet_info/ethernet_info_text_sensor.h +0 -3
  199. esphome/components/event/__init__.py +0 -1
  200. esphome/components/factory_reset/__init__.py +92 -0
  201. esphome/components/factory_reset/factory_reset.cpp +76 -0
  202. esphome/components/factory_reset/factory_reset.h +43 -0
  203. esphome/components/fan/__init__.py +0 -1
  204. esphome/components/fan/fan_traits.h +16 -0
  205. esphome/components/fastled_base/fastled_light.cpp +0 -1
  206. esphome/components/fastled_spi/light.py +1 -3
  207. esphome/components/fingerprint_grow/fingerprint_grow.cpp +0 -2
  208. esphome/components/fs3000/fs3000.cpp +0 -2
  209. esphome/components/ft5x06/touchscreen/ft5x06_touchscreen.cpp +0 -2
  210. esphome/components/ft63x6/ft63x6.cpp +0 -1
  211. esphome/components/gdk101/gdk101.cpp +0 -1
  212. esphome/components/gl_r01_i2c/gl_r01_i2c.cpp +0 -1
  213. esphome/components/gl_r01_i2c/sensor.py +1 -1
  214. esphome/components/gpio/one_wire/gpio_one_wire.cpp +0 -1
  215. esphome/components/gpio/switch/gpio_switch.cpp +0 -2
  216. esphome/components/gpio_expander/cached_gpio.h +24 -15
  217. esphome/components/gps/__init__.py +6 -2
  218. esphome/components/gps/gps.cpp +50 -49
  219. esphome/components/gps/gps.h +4 -8
  220. esphome/components/gps/time/gps_time.cpp +3 -9
  221. esphome/components/gps/time/gps_time.h +4 -7
  222. esphome/components/graph/__init__.py +1 -1
  223. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.cpp +0 -1
  224. esphome/components/grove_tb6612fng/grove_tb6612fng.cpp +0 -1
  225. esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +21 -12
  226. esphome/components/gt911/touchscreen/gt911_touchscreen.h +26 -2
  227. esphome/components/haier/climate.py +5 -10
  228. esphome/components/haier/haier_base.cpp +0 -1
  229. esphome/components/hbridge/switch/hbridge_switch.cpp +0 -2
  230. esphome/components/hdc1080/hdc1080.cpp +0 -2
  231. esphome/components/heatpumpir/climate.py +2 -2
  232. esphome/components/hlw8012/hlw8012.cpp +0 -1
  233. esphome/components/hm3301/hm3301.cpp +0 -1
  234. esphome/components/hmc5883l/hmc5883l.cpp +0 -1
  235. esphome/components/homeassistant/__init__.py +1 -0
  236. esphome/components/homeassistant/number/__init__.py +1 -0
  237. esphome/components/homeassistant/number/homeassistant_number.cpp +11 -7
  238. esphome/components/homeassistant/switch/__init__.py +1 -0
  239. esphome/components/homeassistant/switch/homeassistant_switch.cpp +9 -5
  240. esphome/components/honeywellabp/honeywellabp.cpp +1 -4
  241. esphome/components/host/__init__.py +2 -0
  242. esphome/components/hte501/hte501.cpp +0 -1
  243. esphome/components/http_request/__init__.py +2 -3
  244. esphome/components/http_request/http_request_idf.cpp +2 -2
  245. esphome/components/htu21d/htu21d.cpp +0 -2
  246. esphome/components/htu31d/htu31d.cpp +0 -2
  247. esphome/components/hx711/hx711.cpp +0 -1
  248. esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +0 -1
  249. esphome/components/hydreon_rgxx/sensor.py +4 -5
  250. esphome/components/i2c/i2c_bus.h +1 -1
  251. esphome/components/i2c/i2c_bus_arduino.cpp +1 -2
  252. esphome/components/i2c/i2c_bus_esp_idf.cpp +192 -17
  253. esphome/components/i2c/i2c_bus_esp_idf.h +11 -1
  254. esphome/components/i2s_audio/__init__.py +6 -5
  255. esphome/components/i2s_audio/i2s_audio.cpp +0 -2
  256. esphome/components/i2s_audio/media_player/i2s_audio_media_player.cpp +1 -4
  257. esphome/components/i2s_audio/microphone/__init__.py +4 -6
  258. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +0 -1
  259. esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +2 -2
  260. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +273 -269
  261. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +19 -34
  262. esphome/components/ili9xxx/display.py +4 -3
  263. esphome/components/ili9xxx/ili9xxx_display.cpp +0 -2
  264. esphome/components/image/__init__.py +123 -92
  265. esphome/components/improv_serial/__init__.py +7 -8
  266. esphome/components/ina219/ina219.cpp +0 -1
  267. esphome/components/ina226/ina226.cpp +0 -2
  268. esphome/components/ina260/ina260.cpp +0 -2
  269. esphome/components/ina2xx_base/__init__.py +2 -5
  270. esphome/components/ina2xx_base/ina2xx_base.cpp +0 -2
  271. esphome/components/ina3221/ina3221.cpp +0 -1
  272. esphome/components/internal_temperature/internal_temperature.cpp +0 -2
  273. esphome/components/interval/interval.h +5 -9
  274. esphome/components/json/__init__.py +1 -1
  275. esphome/components/kmeteriso/kmeteriso.cpp +0 -2
  276. esphome/components/lc709203f/lc709203f.cpp +0 -2
  277. esphome/components/lcd_gpio/display.py +1 -3
  278. esphome/components/lcd_gpio/gpio_lcd_display.cpp +0 -1
  279. esphome/components/lcd_pcf8574/pcf8574_display.cpp +0 -1
  280. esphome/components/ld2410/__init__.py +4 -6
  281. esphome/components/ld2410/binary_sensor.py +4 -0
  282. esphome/components/ld2410/ld2410.cpp +56 -100
  283. esphome/components/ld2410/ld2410.h +17 -15
  284. esphome/components/ld2410/sensor.py +24 -10
  285. esphome/components/ld2412/__init__.py +46 -0
  286. esphome/components/ld2412/binary_sensor.py +70 -0
  287. esphome/components/ld2412/button/__init__.py +74 -0
  288. esphome/components/ld2412/button/factory_reset_button.cpp +9 -0
  289. esphome/components/ld2412/button/factory_reset_button.h +18 -0
  290. esphome/components/ld2412/button/query_button.cpp +9 -0
  291. esphome/components/ld2412/button/query_button.h +18 -0
  292. esphome/components/ld2412/button/restart_button.cpp +9 -0
  293. esphome/components/ld2412/button/restart_button.h +18 -0
  294. esphome/components/ld2412/button/start_dynamic_background_correction_button.cpp +11 -0
  295. esphome/components/ld2412/button/start_dynamic_background_correction_button.h +18 -0
  296. esphome/components/ld2412/ld2412.cpp +861 -0
  297. esphome/components/ld2412/ld2412.h +141 -0
  298. esphome/components/ld2412/number/__init__.py +126 -0
  299. esphome/components/ld2412/number/gate_threshold_number.cpp +14 -0
  300. esphome/components/ld2412/number/gate_threshold_number.h +19 -0
  301. esphome/components/ld2412/number/light_threshold_number.cpp +12 -0
  302. esphome/components/ld2412/number/light_threshold_number.h +18 -0
  303. esphome/components/ld2412/number/max_distance_timeout_number.cpp +12 -0
  304. esphome/components/ld2412/number/max_distance_timeout_number.h +18 -0
  305. esphome/components/ld2412/select/__init__.py +82 -0
  306. esphome/components/ld2412/select/baud_rate_select.cpp +12 -0
  307. esphome/components/ld2412/select/baud_rate_select.h +18 -0
  308. esphome/components/ld2412/select/distance_resolution_select.cpp +12 -0
  309. esphome/components/ld2412/select/distance_resolution_select.h +18 -0
  310. esphome/components/ld2412/select/light_out_control_select.cpp +12 -0
  311. esphome/components/ld2412/select/light_out_control_select.h +18 -0
  312. esphome/components/ld2412/sensor.py +124 -0
  313. esphome/components/ld2412/switch/__init__.py +45 -0
  314. esphome/components/ld2412/switch/bluetooth_switch.cpp +12 -0
  315. esphome/components/ld2412/switch/bluetooth_switch.h +18 -0
  316. esphome/components/ld2412/switch/engineering_mode_switch.cpp +12 -0
  317. esphome/components/ld2412/switch/engineering_mode_switch.h +18 -0
  318. esphome/components/ld2412/text_sensor.py +34 -0
  319. esphome/components/ld2420/ld2420.cpp +0 -1
  320. esphome/components/ld2450/__init__.py +3 -4
  321. esphome/components/ld2450/binary_sensor.py +3 -0
  322. esphome/components/ld2450/ld2450.cpp +77 -165
  323. esphome/components/ld2450/ld2450.h +26 -54
  324. esphome/components/ld2450/sensor.py +120 -6
  325. esphome/components/ld2450/text_sensor.py +5 -4
  326. esphome/components/ld24xx/__init__.py +1 -0
  327. esphome/components/ld24xx/ld24xx.h +65 -0
  328. esphome/components/ledc/ledc_output.cpp +0 -1
  329. esphome/components/libretiny/__init__.py +2 -0
  330. esphome/components/light/__init__.py +0 -1
  331. esphome/components/light/effects.py +70 -45
  332. esphome/components/light/light_call.cpp +101 -66
  333. esphome/components/light/light_color_values.h +16 -11
  334. esphome/components/light/light_json_schema.cpp +46 -44
  335. esphome/components/light/light_state.cpp +8 -11
  336. esphome/components/light/light_traits.h +17 -0
  337. esphome/components/lightwaverf/lightwaverf.cpp +0 -2
  338. esphome/components/lilygo_t5_47/touchscreen/lilygo_t5_47_touchscreen.cpp +0 -1
  339. esphome/components/lock/__init__.py +0 -1
  340. esphome/components/logger/__init__.py +31 -9
  341. esphome/components/logger/logger.cpp +12 -7
  342. esphome/components/logger/logger.h +25 -14
  343. esphome/components/logger/logger_esp32.cpp +2 -7
  344. esphome/components/logger/logger_esp8266.cpp +2 -4
  345. esphome/components/logger/logger_host.cpp +2 -4
  346. esphome/components/logger/logger_libretiny.cpp +2 -4
  347. esphome/components/logger/logger_rp2040.cpp +2 -4
  348. esphome/components/logger/logger_zephyr.cpp +86 -0
  349. esphome/components/logger/select/logger_level_select.cpp +2 -4
  350. esphome/components/logger/select/logger_level_select.h +2 -4
  351. esphome/components/logger/task_log_buffer.cpp +2 -4
  352. esphome/components/logger/task_log_buffer.h +2 -4
  353. esphome/components/lps22/sensor.py +5 -5
  354. esphome/components/ltr390/ltr390.cpp +0 -2
  355. esphome/components/ltr501/ltr501.cpp +0 -1
  356. esphome/components/ltr_als_ps/ltr_als_ps.cpp +0 -1
  357. esphome/components/lvgl/__init__.py +14 -13
  358. esphome/components/lvgl/automation.py +2 -4
  359. esphome/components/lvgl/defines.py +0 -2
  360. esphome/components/lvgl/helpers.py +1 -1
  361. esphome/components/lvgl/lv_validation.py +7 -4
  362. esphome/components/lvgl/lvgl_esphome.cpp +2 -3
  363. esphome/components/lvgl/styles.py +2 -2
  364. esphome/components/lvgl/types.py +1 -1
  365. esphome/components/lvgl/widgets/__init__.py +2 -2
  366. esphome/components/lvgl/widgets/arc.py +14 -11
  367. esphome/components/lvgl/widgets/buttonmatrix.py +1 -1
  368. esphome/components/lvgl/widgets/qrcode.py +7 -7
  369. esphome/components/lvgl/widgets/spinner.py +6 -6
  370. esphome/components/lvgl/widgets/switch.py +2 -2
  371. esphome/components/lvgl/widgets/tabview.py +3 -3
  372. esphome/components/m5stack_8angle/m5stack_8angle.cpp +0 -1
  373. esphome/components/matrix_keypad/__init__.py +4 -3
  374. esphome/components/max17043/max17043.cpp +0 -2
  375. esphome/components/max31855/max31855.cpp +1 -4
  376. esphome/components/max31856/max31856.cpp +0 -4
  377. esphome/components/max31865/max31865.cpp +0 -1
  378. esphome/components/max44009/max44009.cpp +0 -1
  379. esphome/components/max6675/max6675.cpp +1 -4
  380. esphome/components/max6956/max6956.cpp +0 -1
  381. esphome/components/max7219/max7219.cpp +0 -1
  382. esphome/components/max7219digit/display.py +1 -1
  383. esphome/components/max7219digit/max7219digit.cpp +0 -1
  384. esphome/components/max9611/max9611.cpp +0 -1
  385. esphome/components/mcp23008/__init__.py +1 -1
  386. esphome/components/mcp23008/mcp23008.cpp +0 -1
  387. esphome/components/mcp23016/mcp23016.cpp +0 -1
  388. esphome/components/mcp23017/__init__.py +1 -1
  389. esphome/components/mcp23017/mcp23017.cpp +0 -1
  390. esphome/components/mcp23s08/__init__.py +1 -1
  391. esphome/components/mcp23s08/mcp23s08.cpp +0 -1
  392. esphome/components/mcp23s17/__init__.py +1 -1
  393. esphome/components/mcp23s17/mcp23s17.cpp +0 -1
  394. esphome/components/mcp23x08_base/__init__.py +2 -0
  395. esphome/components/mcp23x08_base/mcp23x08_base.cpp +9 -7
  396. esphome/components/mcp23x08_base/mcp23x08_base.h +9 -4
  397. esphome/components/mcp23x17_base/__init__.py +2 -0
  398. esphome/components/mcp23x17_base/mcp23x17_base.cpp +20 -7
  399. esphome/components/mcp23x17_base/mcp23x17_base.h +9 -4
  400. esphome/components/mcp23xxx_base/__init__.py +11 -5
  401. esphome/components/mcp23xxx_base/mcp23xxx_base.cpp +15 -12
  402. esphome/components/mcp23xxx_base/mcp23xxx_base.h +8 -7
  403. esphome/components/mcp3008/mcp3008.cpp +1 -4
  404. esphome/components/mcp3204/mcp3204.cpp +1 -4
  405. esphome/components/mcp4461/mcp4461.cpp +0 -1
  406. esphome/components/mcp4725/mcp4725.cpp +0 -1
  407. esphome/components/mcp4728/mcp4728.cpp +0 -1
  408. esphome/components/mcp9600/mcp9600.cpp +0 -2
  409. esphome/components/mcp9808/mcp9808.cpp +0 -2
  410. esphome/components/mdns/__init__.py +3 -0
  411. esphome/components/mdns/mdns_component.cpp +2 -0
  412. esphome/components/mdns/mdns_component.h +4 -0
  413. esphome/components/media_player/__init__.py +40 -0
  414. esphome/components/media_player/automation.h +16 -0
  415. esphome/components/media_player/media_player.cpp +13 -0
  416. esphome/components/media_player/media_player.h +50 -3
  417. esphome/components/micro_wake_word/micro_wake_word.cpp +0 -3
  418. esphome/components/mics_4514/mics_4514.cpp +1 -6
  419. esphome/components/midea/ir_transmitter.h +4 -4
  420. esphome/components/mipi/__init__.py +416 -0
  421. esphome/components/mipi_dsi/__init__.py +5 -0
  422. esphome/components/mipi_dsi/display.py +233 -0
  423. esphome/components/mipi_dsi/mipi_dsi.cpp +379 -0
  424. esphome/components/mipi_dsi/mipi_dsi.h +123 -0
  425. esphome/components/mipi_dsi/models/__init__.py +0 -0
  426. esphome/components/mipi_dsi/models/guition.py +38 -0
  427. esphome/components/mipi_dsi/models/m5stack.py +57 -0
  428. esphome/components/mipi_dsi/models/waveshare.py +105 -0
  429. esphome/components/mipi_rgb/models/lilygo.py +0 -0
  430. esphome/components/mipi_spi/__init__.py +0 -9
  431. esphome/components/mipi_spi/display.py +220 -256
  432. esphome/components/mipi_spi/mipi_spi.cpp +1 -485
  433. esphome/components/mipi_spi/mipi_spi.h +556 -108
  434. esphome/components/mipi_spi/models/__init__.py +0 -65
  435. esphome/components/mipi_spi/models/adafruit.py +30 -0
  436. esphome/components/mipi_spi/models/amoled.py +41 -5
  437. esphome/components/mipi_spi/models/ili.py +5 -5
  438. esphome/components/mipi_spi/models/jc.py +1 -3
  439. esphome/components/mipi_spi/models/lilygo.py +1 -1
  440. esphome/components/mipi_spi/models/waveshare.py +16 -1
  441. esphome/components/mixer/speaker/__init__.py +4 -5
  442. esphome/components/mlx90393/sensor.py +7 -5
  443. esphome/components/mlx90393/sensor_mlx90393.cpp +0 -1
  444. esphome/components/mlx90614/mlx90614.cpp +0 -1
  445. esphome/components/mmc5603/mmc5603.cpp +0 -1
  446. esphome/components/mmc5983/mmc5983.cpp +0 -2
  447. esphome/components/mpl3115a2/mpl3115a2.cpp +0 -2
  448. esphome/components/mpr121/__init__.py +7 -6
  449. esphome/components/mpr121/mpr121.cpp +0 -1
  450. esphome/components/mpu6050/mpu6050.cpp +0 -1
  451. esphome/components/mpu6886/mpu6886.cpp +0 -1
  452. esphome/components/mqtt/__init__.py +1 -2
  453. esphome/components/mqtt/mqtt_button.cpp +1 -1
  454. esphome/components/mqtt/mqtt_client.cpp +0 -1
  455. esphome/components/mqtt/mqtt_component.cpp +8 -14
  456. esphome/components/mqtt/mqtt_component.h +0 -7
  457. esphome/components/mqtt/mqtt_sensor.cpp +0 -1
  458. esphome/components/mqtt/mqtt_sensor.h +0 -1
  459. esphome/components/mqtt/mqtt_text_sensor.cpp +0 -1
  460. esphome/components/mqtt/mqtt_text_sensor.h +0 -1
  461. esphome/components/ms5611/ms5611.cpp +0 -1
  462. esphome/components/ms8607/ms8607.cpp +0 -1
  463. esphome/components/msa3xx/msa3xx.cpp +0 -2
  464. esphome/components/my9231/my9231.cpp +0 -2
  465. esphome/components/nau7802/nau7802.cpp +0 -1
  466. esphome/components/neopixelbus/light.py +3 -0
  467. esphome/components/network/util.cpp +29 -0
  468. esphome/components/nextion/nextion.cpp +0 -1
  469. esphome/components/nfc/binary_sensor/{binary_sensor.cpp → nfc_binary_sensor.cpp} +1 -1
  470. esphome/components/npi19/npi19.cpp +0 -2
  471. esphome/components/nrf52/__init__.py +223 -0
  472. esphome/components/nrf52/boards.py +34 -0
  473. esphome/components/nrf52/const.py +18 -0
  474. esphome/components/nrf52/gpio.py +79 -0
  475. esphome/components/number/__init__.py +2 -1
  476. esphome/components/one_wire/__init__.py +1 -2
  477. esphome/components/one_wire/one_wire.cpp +0 -2
  478. esphome/components/one_wire/one_wire.h +0 -2
  479. esphome/components/opentherm/hub.cpp +0 -1
  480. esphome/components/opentherm/number/__init__.py +2 -2
  481. esphome/components/openthread/__init__.py +2 -3
  482. esphome/components/openthread/openthread.cpp +30 -13
  483. esphome/components/openthread/openthread.h +3 -0
  484. esphome/components/openthread/openthread_esp.cpp +3 -1
  485. esphome/components/opt3001/sensor.py +2 -6
  486. esphome/components/output/__init__.py +38 -0
  487. esphome/components/output/automation.h +24 -0
  488. esphome/components/output/switch/output_switch.cpp +0 -2
  489. esphome/components/packages/__init__.py +1 -2
  490. esphome/components/packet_transport/__init__.py +4 -3
  491. esphome/components/pca6416a/pca6416a.cpp +0 -1
  492. esphome/components/pca9554/pca9554.cpp +0 -1
  493. esphome/components/pca9685/pca9685_output.cpp +0 -2
  494. esphome/components/pcf85063/pcf85063.cpp +0 -1
  495. esphome/components/pcf8563/pcf8563.cpp +0 -1
  496. esphome/components/pcf8574/pcf8574.cpp +0 -1
  497. esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +0 -1
  498. esphome/components/pipsolar/sensor/__init__.py +1 -1
  499. esphome/components/pm2005/pm2005.cpp +0 -1
  500. esphome/components/pmsa003i/pmsa003i.cpp +0 -2
  501. esphome/components/pmwcs3/sensor.py +1 -2
  502. esphome/components/pn532/pn532.cpp +0 -2
  503. esphome/components/pn532_spi/pn532_spi.cpp +0 -2
  504. esphome/components/power_supply/power_supply.cpp +7 -10
  505. esphome/components/power_supply/power_supply.h +1 -1
  506. esphome/components/psram/__init__.py +2 -1
  507. esphome/components/pulse_counter/pulse_counter_sensor.cpp +0 -1
  508. esphome/components/pulse_counter/sensor.py +9 -6
  509. esphome/components/pylontech/pylontech.cpp +0 -1
  510. esphome/components/qmc5883l/qmc5883l.cpp +0 -1
  511. esphome/components/qmp6988/qmp6988.cpp +0 -2
  512. esphome/components/qspi_dbi/display.py +2 -3
  513. esphome/components/qspi_dbi/qspi_dbi.cpp +0 -2
  514. esphome/components/qwiic_pir/binary_sensor.py +2 -3
  515. esphome/components/qwiic_pir/qwiic_pir.cpp +0 -2
  516. esphome/components/rc522/rc522.cpp +9 -31
  517. esphome/components/rc522_spi/rc522_spi.cpp +0 -1
  518. esphome/components/remote_base/__init__.py +5 -6
  519. esphome/components/remote_receiver/remote_receiver_esp32.cpp +0 -1
  520. esphome/components/remote_receiver/remote_receiver_esp8266.cpp +0 -1
  521. esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -1
  522. esphome/components/remote_transmitter/__init__.py +26 -0
  523. esphome/components/remote_transmitter/automation.h +18 -0
  524. esphome/components/remote_transmitter/remote_transmitter.h +2 -1
  525. esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +0 -1
  526. esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +2 -0
  527. esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +2 -0
  528. esphome/components/resampler/speaker/__init__.py +4 -5
  529. esphome/components/rf_bridge/__init__.py +4 -8
  530. esphome/components/rotary_encoder/rotary_encoder.cpp +0 -2
  531. esphome/components/rp2040/__init__.py +3 -1
  532. esphome/components/rp2040_pio_led_strip/led_strip.cpp +0 -2
  533. esphome/components/rp2040_pio_led_strip/light.py +1 -2
  534. esphome/components/rp2040_pwm/rp2040_pwm.cpp +1 -5
  535. esphome/components/rpi_dpi_rgb/display.py +13 -15
  536. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +0 -3
  537. esphome/components/runtime_stats/__init__.py +34 -0
  538. esphome/components/runtime_stats/runtime_stats.cpp +102 -0
  539. esphome/components/runtime_stats/runtime_stats.h +132 -0
  540. esphome/components/scd30/scd30.cpp +0 -2
  541. esphome/components/scd30/sensor.py +1 -2
  542. esphome/components/scd4x/scd4x.cpp +0 -1
  543. esphome/components/scd4x/sensor.py +1 -3
  544. esphome/components/sdl/display.py +3 -1
  545. esphome/components/sdl/sdl_esphome.cpp +0 -2
  546. esphome/components/sdp3x/sdp3x.cpp +0 -2
  547. esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.cpp +0 -2
  548. esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp +0 -3
  549. esphome/components/select/__init__.py +2 -3
  550. esphome/components/select/select_traits.cpp +1 -1
  551. esphome/components/select/select_traits.h +1 -1
  552. esphome/components/sen0321/sen0321.cpp +0 -1
  553. esphome/components/sen5x/sen5x.cpp +0 -2
  554. esphome/components/sensor/__init__.py +36 -4
  555. esphome/components/sensor/filter.cpp +49 -10
  556. esphome/components/sensor/filter.h +22 -7
  557. esphome/components/sensor/sensor.cpp +0 -1
  558. esphome/components/sensor/sensor.h +0 -9
  559. esphome/components/sfa30/sfa30.cpp +0 -4
  560. esphome/components/sgp30/sgp30.cpp +0 -2
  561. esphome/components/sgp4x/sensor.py +1 -1
  562. esphome/components/sgp4x/sgp4x.cpp +0 -2
  563. esphome/components/shelly_dimmer/shelly_dimmer.cpp +0 -2
  564. esphome/components/sht3xd/sht3xd.cpp +0 -2
  565. esphome/components/sht4x/sht4x.cpp +0 -2
  566. esphome/components/shtcx/shtcx.cpp +0 -1
  567. esphome/components/sim800l/__init__.py +2 -4
  568. esphome/components/sm16716/sm16716.cpp +0 -1
  569. esphome/components/sm2135/sm2135.cpp +0 -1
  570. esphome/components/sm2235/sm2235.cpp +0 -1
  571. esphome/components/sm2335/sm2335.cpp +0 -1
  572. esphome/components/sn74hc165/sn74hc165.cpp +0 -1
  573. esphome/components/sn74hc595/sn74hc595.cpp +0 -1
  574. esphome/components/sntp/sntp_component.cpp +0 -1
  575. esphome/components/sound_level/sensor.py +1 -1
  576. esphome/components/speaker/media_player/__init__.py +21 -33
  577. esphome/components/speaker/media_player/audio_pipeline.cpp +4 -7
  578. esphome/components/spi/__init__.py +29 -13
  579. esphome/components/spi/spi.cpp +0 -2
  580. esphome/components/spi_device/spi_device.cpp +1 -4
  581. esphome/components/sprinkler/__init__.py +4 -4
  582. esphome/components/sps30/sps30.cpp +0 -1
  583. esphome/components/ssd1306_base/__init__.py +11 -11
  584. esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
  585. esphome/components/ssd1306_i2c/ssd1306_i2c.cpp +0 -1
  586. esphome/components/ssd1306_spi/ssd1306_spi.cpp +0 -1
  587. esphome/components/ssd1322_spi/ssd1322_spi.cpp +0 -1
  588. esphome/components/ssd1325_spi/ssd1325_spi.cpp +0 -1
  589. esphome/components/ssd1327_i2c/ssd1327_i2c.cpp +0 -1
  590. esphome/components/ssd1327_spi/ssd1327_spi.cpp +0 -1
  591. esphome/components/ssd1331_spi/ssd1331_spi.cpp +0 -1
  592. esphome/components/ssd1351_spi/ssd1351_spi.cpp +0 -1
  593. esphome/components/st7567_i2c/st7567_i2c.cpp +0 -1
  594. esphome/components/st7567_spi/st7567_spi.cpp +0 -1
  595. esphome/components/st7701s/display.py +10 -14
  596. esphome/components/st7701s/st7701s.cpp +0 -3
  597. esphome/components/st7735/st7735.cpp +0 -1
  598. esphome/components/st7789v/st7789v.cpp +0 -1
  599. esphome/components/st7920/st7920.cpp +0 -1
  600. esphome/components/status_led/light/status_led_light.cpp +0 -2
  601. esphome/components/status_led/status_led.cpp +0 -1
  602. esphome/components/stepper/__init__.py +2 -4
  603. esphome/components/sts3x/sts3x.cpp +0 -1
  604. esphome/components/substitutions/__init__.py +10 -16
  605. esphome/components/substitutions/jinja.py +24 -1
  606. esphome/components/sun/__init__.py +2 -3
  607. esphome/components/switch/__init__.py +31 -1
  608. esphome/components/switch/automation.h +24 -0
  609. esphome/components/switch/switch.cpp +8 -0
  610. esphome/components/switch/switch.h +8 -0
  611. esphome/components/sx126x/sx126x.cpp +0 -2
  612. esphome/components/sx127x/sx127x.cpp +0 -2
  613. esphome/components/sx1509/__init__.py +7 -5
  614. esphome/components/sx1509/output/sx1509_float_output.cpp +1 -1
  615. esphome/components/sx1509/sx1509.cpp +0 -2
  616. esphome/components/syslog/esphome_syslog.cpp +1 -1
  617. esphome/components/tc74/tc74.cpp +0 -1
  618. esphome/components/tca9548a/tca9548a.cpp +0 -1
  619. esphome/components/tca9555/tca9555.cpp +0 -1
  620. esphome/components/tcs34725/tcs34725.cpp +0 -1
  621. esphome/components/tee501/tee501.cpp +0 -1
  622. esphome/components/tem3200/tem3200.cpp +0 -2
  623. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +0 -1
  624. esphome/components/template/cover/template_cover.cpp +0 -1
  625. esphome/components/template/select/template_select.cpp +0 -1
  626. esphome/components/template/text/template_text.cpp +0 -2
  627. esphome/components/template/valve/template_valve.cpp +0 -1
  628. esphome/components/text/__init__.py +0 -1
  629. esphome/components/text/text_traits.h +2 -0
  630. esphome/components/text_sensor/__init__.py +2 -1
  631. esphome/components/text_sensor/text_sensor.cpp +0 -2
  632. esphome/components/text_sensor/text_sensor.h +0 -8
  633. esphome/components/thermostat/climate.py +4 -4
  634. esphome/components/time/__init__.py +7 -4
  635. esphome/components/time/real_time_clock.cpp +16 -3
  636. esphome/components/tlc59208f/tlc59208f_output.cpp +0 -2
  637. esphome/components/tlc5947/tlc5947.cpp +0 -2
  638. esphome/components/tlc5971/tlc5971.cpp +0 -2
  639. esphome/components/tm1621/tm1621.cpp +0 -2
  640. esphome/components/tm1637/tm1637.cpp +0 -2
  641. esphome/components/tm1638/tm1638.cpp +0 -2
  642. esphome/components/tm1651/__init__.py +45 -48
  643. esphome/components/tm1651/tm1651.cpp +213 -47
  644. esphome/components/tm1651/tm1651.h +37 -32
  645. esphome/components/tmp117/tmp117.cpp +0 -2
  646. esphome/components/tsl2561/tsl2561.cpp +0 -1
  647. esphome/components/tsl2591/tsl2591.cpp +0 -1
  648. esphome/components/tt21100/touchscreen/tt21100.cpp +0 -2
  649. esphome/components/ttp229_bsf/ttp229_bsf.cpp +0 -1
  650. esphome/components/ttp229_lsf/ttp229_lsf.cpp +0 -1
  651. esphome/components/tuya/climate/__init__.py +9 -10
  652. esphome/components/tuya/number/__init__.py +8 -6
  653. esphome/components/tx20/tx20.cpp +0 -1
  654. esphome/components/uart/uart_component_esp32_arduino.cpp +0 -1
  655. esphome/components/uart/uart_component_esp8266.cpp +0 -1
  656. esphome/components/uart/uart_component_esp_idf.cpp +0 -2
  657. esphome/components/uart/uart_component_libretiny.cpp +0 -2
  658. esphome/components/uart/uart_component_rp2040.cpp +0 -2
  659. esphome/components/udp/__init__.py +1 -1
  660. esphome/components/ufire_ec/sensor.py +1 -2
  661. esphome/components/ufire_ec/ufire_ec.cpp +0 -2
  662. esphome/components/ufire_ise/sensor.py +1 -2
  663. esphome/components/ufire_ise/ufire_ise.cpp +0 -2
  664. esphome/components/ultrasonic/ultrasonic_sensor.cpp +0 -1
  665. esphome/components/update/__init__.py +0 -1
  666. esphome/components/uptime/sensor/uptime_seconds_sensor.cpp +0 -1
  667. esphome/components/uptime/sensor/uptime_seconds_sensor.h +0 -2
  668. esphome/components/usb_host/usb_host_client.cpp +0 -1
  669. esphome/components/usb_host/usb_host_component.cpp +0 -1
  670. esphome/components/valve/__init__.py +0 -1
  671. esphome/components/veml3235/veml3235.cpp +0 -3
  672. esphome/components/veml7700/veml7700.cpp +0 -2
  673. esphome/components/version/version_text_sensor.cpp +0 -1
  674. esphome/components/version/version_text_sensor.h +0 -1
  675. esphome/components/vl53l0x/vl53l0x_sensor.cpp +0 -4
  676. esphome/components/voice_assistant/voice_assistant.cpp +9 -8
  677. esphome/components/web_server/__init__.py +13 -0
  678. esphome/components/web_server/web_server.cpp +187 -352
  679. esphome/components/web_server/web_server.h +61 -1
  680. esphome/components/web_server_base/__init__.py +1 -1
  681. esphome/components/web_server_base/web_server_base.cpp +2 -0
  682. esphome/components/web_server_base/web_server_base.h +6 -0
  683. esphome/components/web_server_idf/web_server_idf.cpp +10 -8
  684. esphome/components/web_server_idf/web_server_idf.h +2 -0
  685. esphome/components/weikai_i2c/weikai_i2c.cpp +1 -2
  686. esphome/components/weikai_spi/weikai_spi.cpp +1 -1
  687. esphome/components/wifi/__init__.py +8 -43
  688. esphome/components/wifi/wifi_component.cpp +100 -36
  689. esphome/components/wifi/wifi_component.h +5 -1
  690. esphome/components/wifi/wifi_component_esp32_arduino.cpp +30 -0
  691. esphome/components/wifi/wifi_component_esp_idf.cpp +30 -0
  692. esphome/components/wifi_info/wifi_info_text_sensor.h +0 -6
  693. esphome/components/wifi_signal/wifi_signal_sensor.h +0 -1
  694. esphome/components/wireguard/wireguard.cpp +0 -2
  695. esphome/components/x9c/x9c.cpp +0 -2
  696. esphome/components/xgzp68xx/xgzp68xx.cpp +0 -1
  697. esphome/components/xl9535/xl9535.cpp +0 -2
  698. esphome/components/zephyr/__init__.py +252 -0
  699. esphome/components/zephyr/const.py +16 -0
  700. esphome/components/zephyr/core.cpp +90 -0
  701. esphome/components/zephyr/gpio.cpp +120 -0
  702. esphome/components/zephyr/gpio.h +38 -0
  703. esphome/components/zephyr/pre_build.py.script +4 -0
  704. esphome/components/zephyr/preferences.cpp +156 -0
  705. esphome/components/zephyr/preferences.h +13 -0
  706. esphome/config.py +38 -16
  707. esphome/config_helpers.py +1 -2
  708. esphome/config_validation.py +8 -15
  709. esphome/const.py +26 -1
  710. esphome/core/__init__.py +88 -51
  711. esphome/core/application.cpp +75 -21
  712. esphome/core/application.h +106 -171
  713. esphome/core/color.h +10 -0
  714. esphome/core/component.cpp +41 -25
  715. esphome/core/component.h +9 -6
  716. esphome/core/component_iterator.cpp +61 -261
  717. esphome/core/component_iterator.h +15 -0
  718. esphome/core/config.py +26 -11
  719. esphome/core/defines.h +40 -2
  720. esphome/core/entity_base.h +18 -0
  721. esphome/core/entity_helpers.py +41 -6
  722. esphome/core/helpers.cpp +8 -15
  723. esphome/core/helpers.h +60 -6
  724. esphome/core/lock_free_queue.h +1 -1
  725. esphome/core/scheduler.cpp +277 -74
  726. esphome/core/scheduler.h +89 -27
  727. esphome/cpp_generator.py +2 -6
  728. esphome/cpp_helpers.py +1 -1
  729. esphome/dashboard/dashboard.py +2 -3
  730. esphome/dashboard/dns.py +2 -8
  731. esphome/dashboard/web_server.py +34 -19
  732. esphome/espota2.py +1 -4
  733. esphome/git.py +3 -1
  734. esphome/helpers.py +23 -4
  735. esphome/log.py +3 -1
  736. esphome/mqtt.py +3 -5
  737. esphome/platformio_api.py +7 -4
  738. esphome/types.py +12 -0
  739. esphome/util.py +20 -8
  740. esphome/voluptuous_schema.py +4 -3
  741. esphome/vscode.py +1 -2
  742. esphome/wizard.py +1 -4
  743. esphome/writer.py +5 -107
  744. esphome/yaml_util.py +7 -5
  745. {esphome-2025.7.5.dist-info → esphome-2025.8.0b1.dist-info}/METADATA +12 -13
  746. {esphome-2025.7.5.dist-info → esphome-2025.8.0b1.dist-info}/RECORD +751 -671
  747. esphome/components/mipi_spi/models/commands.py +0 -82
  748. /esphome/components/nfc/binary_sensor/{binary_sensor.h → nfc_binary_sensor.h} +0 -0
  749. {esphome-2025.7.5.dist-info → esphome-2025.8.0b1.dist-info}/WHEEL +0 -0
  750. {esphome-2025.7.5.dist-info → esphome-2025.8.0b1.dist-info}/entry_points.txt +0 -0
  751. {esphome-2025.7.5.dist-info → esphome-2025.8.0b1.dist-info}/licenses/LICENSE +0 -0
  752. {esphome-2025.7.5.dist-info → esphome-2025.8.0b1.dist-info}/top_level.txt +0 -0
@@ -9,6 +9,28 @@ namespace light {
9
9
 
10
10
  static const char *const TAG = "light";
11
11
 
12
+ // Helper functions to reduce code size for logging
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);
16
+ }
17
+
18
+ static void log_feature_not_supported(const char *name, const char *feature) {
19
+ ESP_LOGW(TAG, "'%s': %s not supported", name, feature);
20
+ }
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);
24
+ }
25
+
26
+ static void log_invalid_parameter(const char *name, const char *message) { ESP_LOGW(TAG, "'%s': %s", name, message); }
27
+ #else
28
+ #define log_validation_warning(name, param_name, val, min, max)
29
+ #define log_feature_not_supported(name, feature)
30
+ #define log_color_mode_not_supported(name, feature)
31
+ #define log_invalid_parameter(name, message)
32
+ #endif
33
+
12
34
  // Macro to reduce repetitive setter code
13
35
  #define IMPLEMENT_LIGHT_CALL_SETTER(name, type, flag) \
14
36
  LightCall &LightCall::set_##name(optional<type>(name)) { \
@@ -44,11 +66,21 @@ static const LogString *color_mode_to_human(ColorMode color_mode) {
44
66
  return LOG_STR("");
45
67
  }
46
68
 
69
+ // Helper to log percentage values
70
+ #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_DEBUG
71
+ static void log_percent(const char *name, const char *param, float value) {
72
+ ESP_LOGD(TAG, " %s: %.0f%%", param, value * 100.0f);
73
+ }
74
+ #else
75
+ #define log_percent(name, param, value)
76
+ #endif
77
+
47
78
  void LightCall::perform() {
48
79
  const char *name = this->parent_->get_name().c_str();
49
80
  LightColorValues v = this->validate_();
81
+ const bool publish = this->get_publish_();
50
82
 
51
- if (this->get_publish_()) {
83
+ if (publish) {
52
84
  ESP_LOGD(TAG, "'%s' Setting:", name);
53
85
 
54
86
  // Only print color mode when it's being changed
@@ -66,11 +98,11 @@ void LightCall::perform() {
66
98
  }
67
99
 
68
100
  if (this->has_brightness()) {
69
- ESP_LOGD(TAG, " Brightness: %.0f%%", v.get_brightness() * 100.0f);
101
+ log_percent(name, "Brightness", v.get_brightness());
70
102
  }
71
103
 
72
104
  if (this->has_color_brightness()) {
73
- ESP_LOGD(TAG, " Color brightness: %.0f%%", v.get_color_brightness() * 100.0f);
105
+ log_percent(name, "Color brightness", v.get_color_brightness());
74
106
  }
75
107
  if (this->has_red() || this->has_green() || this->has_blue()) {
76
108
  ESP_LOGD(TAG, " Red: %.0f%%, Green: %.0f%%, Blue: %.0f%%", v.get_red() * 100.0f, v.get_green() * 100.0f,
@@ -78,7 +110,7 @@ void LightCall::perform() {
78
110
  }
79
111
 
80
112
  if (this->has_white()) {
81
- ESP_LOGD(TAG, " White: %.0f%%", v.get_white() * 100.0f);
113
+ log_percent(name, "White", v.get_white());
82
114
  }
83
115
  if (this->has_color_temperature()) {
84
116
  ESP_LOGD(TAG, " Color temperature: %.1f mireds", v.get_color_temperature());
@@ -92,26 +124,26 @@ void LightCall::perform() {
92
124
 
93
125
  if (this->has_flash_()) {
94
126
  // FLASH
95
- if (this->get_publish_()) {
127
+ if (publish) {
96
128
  ESP_LOGD(TAG, " Flash length: %.1fs", this->flash_length_ / 1e3f);
97
129
  }
98
130
 
99
- this->parent_->start_flash_(v, this->flash_length_, this->get_publish_());
131
+ this->parent_->start_flash_(v, this->flash_length_, publish);
100
132
  } else if (this->has_transition_()) {
101
133
  // TRANSITION
102
- if (this->get_publish_()) {
134
+ if (publish) {
103
135
  ESP_LOGD(TAG, " Transition length: %.1fs", this->transition_length_ / 1e3f);
104
136
  }
105
137
 
106
138
  // Special case: Transition and effect can be set when turning off
107
139
  if (this->has_effect_()) {
108
- if (this->get_publish_()) {
140
+ if (publish) {
109
141
  ESP_LOGD(TAG, " Effect: 'None'");
110
142
  }
111
143
  this->parent_->stop_effect_();
112
144
  }
113
145
 
114
- this->parent_->start_transition_(v, this->transition_length_, this->get_publish_());
146
+ this->parent_->start_transition_(v, this->transition_length_, publish);
115
147
 
116
148
  } else if (this->has_effect_()) {
117
149
  // EFFECT
@@ -122,7 +154,7 @@ void LightCall::perform() {
122
154
  effect_s = this->parent_->effects_[this->effect_ - 1]->get_name().c_str();
123
155
  }
124
156
 
125
- if (this->get_publish_()) {
157
+ if (publish) {
126
158
  ESP_LOGD(TAG, " Effect: '%s'", effect_s);
127
159
  }
128
160
 
@@ -133,13 +165,13 @@ void LightCall::perform() {
133
165
  this->parent_->set_immediately_(v, true);
134
166
  } else {
135
167
  // INSTANT CHANGE
136
- this->parent_->set_immediately_(v, this->get_publish_());
168
+ this->parent_->set_immediately_(v, publish);
137
169
  }
138
170
 
139
171
  if (!this->has_transition_()) {
140
172
  this->parent_->target_state_reached_callback_.call();
141
173
  }
142
- if (this->get_publish_()) {
174
+ if (publish) {
143
175
  this->parent_->publish_state();
144
176
  }
145
177
  if (this->get_save_()) {
@@ -169,19 +201,19 @@ LightColorValues LightCall::validate_() {
169
201
 
170
202
  // Brightness exists check
171
203
  if (this->has_brightness() && this->brightness_ > 0.0f && !(color_mode & ColorCapability::BRIGHTNESS)) {
172
- ESP_LOGW(TAG, "'%s': setting brightness not supported", name);
204
+ log_feature_not_supported(name, "brightness");
173
205
  this->set_flag_(FLAG_HAS_BRIGHTNESS, false);
174
206
  }
175
207
 
176
208
  // Transition length possible check
177
209
  if (this->has_transition_() && this->transition_length_ != 0 && !(color_mode & ColorCapability::BRIGHTNESS)) {
178
- ESP_LOGW(TAG, "'%s': transitions not supported", name);
210
+ log_feature_not_supported(name, "transitions");
179
211
  this->set_flag_(FLAG_HAS_TRANSITION, false);
180
212
  }
181
213
 
182
214
  // Color brightness exists check
183
215
  if (this->has_color_brightness() && this->color_brightness_ > 0.0f && !(color_mode & ColorCapability::RGB)) {
184
- ESP_LOGW(TAG, "'%s': color mode does not support setting RGB brightness", name);
216
+ log_color_mode_not_supported(name, "RGB brightness");
185
217
  this->set_flag_(FLAG_HAS_COLOR_BRIGHTNESS, false);
186
218
  }
187
219
 
@@ -189,7 +221,7 @@ LightColorValues LightCall::validate_() {
189
221
  if ((this->has_red() && this->red_ > 0.0f) || (this->has_green() && this->green_ > 0.0f) ||
190
222
  (this->has_blue() && this->blue_ > 0.0f)) {
191
223
  if (!(color_mode & ColorCapability::RGB)) {
192
- ESP_LOGW(TAG, "'%s': color mode does not support setting RGB color", name);
224
+ log_color_mode_not_supported(name, "RGB color");
193
225
  this->set_flag_(FLAG_HAS_RED, false);
194
226
  this->set_flag_(FLAG_HAS_GREEN, false);
195
227
  this->set_flag_(FLAG_HAS_BLUE, false);
@@ -199,21 +231,21 @@ LightColorValues LightCall::validate_() {
199
231
  // White value exists check
200
232
  if (this->has_white() && this->white_ > 0.0f &&
201
233
  !(color_mode & ColorCapability::WHITE || color_mode & ColorCapability::COLD_WARM_WHITE)) {
202
- ESP_LOGW(TAG, "'%s': color mode does not support setting white value", name);
234
+ log_color_mode_not_supported(name, "white value");
203
235
  this->set_flag_(FLAG_HAS_WHITE, false);
204
236
  }
205
237
 
206
238
  // Color temperature exists check
207
239
  if (this->has_color_temperature() &&
208
240
  !(color_mode & ColorCapability::COLOR_TEMPERATURE || color_mode & ColorCapability::COLD_WARM_WHITE)) {
209
- ESP_LOGW(TAG, "'%s': color mode does not support setting color temperature", name);
241
+ log_color_mode_not_supported(name, "color temperature");
210
242
  this->set_flag_(FLAG_HAS_COLOR_TEMPERATURE, false);
211
243
  }
212
244
 
213
245
  // Cold/warm white value exists check
214
246
  if ((this->has_cold_white() && this->cold_white_ > 0.0f) || (this->has_warm_white() && this->warm_white_ > 0.0f)) {
215
247
  if (!(color_mode & ColorCapability::COLD_WARM_WHITE)) {
216
- ESP_LOGW(TAG, "'%s': color mode does not support setting cold/warm white value", name);
248
+ log_color_mode_not_supported(name, "cold/warm white value");
217
249
  this->set_flag_(FLAG_HAS_COLD_WHITE, false);
218
250
  this->set_flag_(FLAG_HAS_WARM_WHITE, false);
219
251
  }
@@ -223,8 +255,7 @@ LightColorValues LightCall::validate_() {
223
255
  if (this->has_##name_()) { \
224
256
  auto val = this->name_##_; \
225
257
  if (val < (min) || val > (max)) { \
226
- ESP_LOGW(TAG, "'%s': %s value %.2f is out of range [%.1f - %.1f]", name, LOG_STR_LITERAL(upper_name), val, \
227
- (min), (max)); \
258
+ log_validation_warning(name, LOG_STR_LITERAL(upper_name), val, (min), (max)); \
228
259
  this->name_##_ = clamp(val, (min), (max)); \
229
260
  } \
230
261
  }
@@ -288,7 +319,7 @@ LightColorValues LightCall::validate_() {
288
319
 
289
320
  // Flash length check
290
321
  if (this->has_flash_() && this->flash_length_ == 0) {
291
- ESP_LOGW(TAG, "'%s': flash length must be greater than zero", name);
322
+ log_invalid_parameter(name, "flash length must be greater than zero");
292
323
  this->set_flag_(FLAG_HAS_FLASH, false);
293
324
  }
294
325
 
@@ -307,13 +338,13 @@ LightColorValues LightCall::validate_() {
307
338
  }
308
339
 
309
340
  if (this->has_effect_() && (this->has_transition_() || this->has_flash_())) {
310
- ESP_LOGW(TAG, "'%s': effect cannot be used with transition/flash", name);
341
+ log_invalid_parameter(name, "effect cannot be used with transition/flash");
311
342
  this->set_flag_(FLAG_HAS_TRANSITION, false);
312
343
  this->set_flag_(FLAG_HAS_FLASH, false);
313
344
  }
314
345
 
315
346
  if (this->has_flash_() && this->has_transition_()) {
316
- ESP_LOGW(TAG, "'%s': flash cannot be used with transition", name);
347
+ log_invalid_parameter(name, "flash cannot be used with transition");
317
348
  this->set_flag_(FLAG_HAS_TRANSITION, false);
318
349
  }
319
350
 
@@ -330,7 +361,7 @@ LightColorValues LightCall::validate_() {
330
361
  }
331
362
 
332
363
  if (this->has_transition_() && !supports_transition) {
333
- ESP_LOGW(TAG, "'%s': transitions not supported", name);
364
+ log_feature_not_supported(name, "transitions");
334
365
  this->set_flag_(FLAG_HAS_TRANSITION, false);
335
366
  }
336
367
 
@@ -340,7 +371,7 @@ LightColorValues LightCall::validate_() {
340
371
  bool target_state = this->has_state() ? this->state_ : v.is_on();
341
372
  if (!this->has_flash_() && !target_state) {
342
373
  if (this->has_effect_()) {
343
- ESP_LOGW(TAG, "'%s': cannot start effect when turning off", name);
374
+ log_invalid_parameter(name, "cannot start effect when turning off");
344
375
  this->set_flag_(FLAG_HAS_EFFECT, false);
345
376
  } else if (this->parent_->active_effect_index_ != 0 && explicit_turn_off_request) {
346
377
  // Auto turn off effect
@@ -364,21 +395,27 @@ void LightCall::transform_parameters_() {
364
395
  // - RGBWW lights with color_interlock=true, which also sets "brightness" and
365
396
  // "color_temperature" (without color_interlock, CW/WW are set directly)
366
397
  // - Legacy Home Assistant (pre-colormode), which sets "white" and "color_temperature"
398
+
399
+ // Cache min/max mireds to avoid repeated calls
400
+ const float min_mireds = traits.get_min_mireds();
401
+ const float max_mireds = traits.get_max_mireds();
402
+
367
403
  if (((this->has_white() && this->white_ > 0.0f) || this->has_color_temperature()) && //
368
404
  (this->color_mode_ & ColorCapability::COLD_WARM_WHITE) && //
369
405
  !(this->color_mode_ & ColorCapability::WHITE) && //
370
406
  !(this->color_mode_ & ColorCapability::COLOR_TEMPERATURE) && //
371
- traits.get_min_mireds() > 0.0f && traits.get_max_mireds() > 0.0f) {
407
+ min_mireds > 0.0f && max_mireds > 0.0f) {
372
408
  ESP_LOGD(TAG, "'%s': setting cold/warm white channels using white/color temperature values",
373
409
  this->parent_->get_name().c_str());
374
410
  if (this->has_color_temperature()) {
375
- const float color_temp = clamp(this->color_temperature_, traits.get_min_mireds(), traits.get_max_mireds());
376
- const float ww_fraction =
377
- (color_temp - traits.get_min_mireds()) / (traits.get_max_mireds() - traits.get_min_mireds());
411
+ const float color_temp = clamp(this->color_temperature_, min_mireds, max_mireds);
412
+ const float range = max_mireds - min_mireds;
413
+ const float ww_fraction = (color_temp - min_mireds) / range;
378
414
  const float cw_fraction = 1.0f - ww_fraction;
379
415
  const float max_cw_ww = std::max(ww_fraction, cw_fraction);
380
- this->cold_white_ = gamma_uncorrect(cw_fraction / max_cw_ww, this->parent_->get_gamma_correct());
381
- this->warm_white_ = gamma_uncorrect(ww_fraction / max_cw_ww, this->parent_->get_gamma_correct());
416
+ const float gamma = this->parent_->get_gamma_correct();
417
+ this->cold_white_ = gamma_uncorrect(cw_fraction / max_cw_ww, gamma);
418
+ this->warm_white_ = gamma_uncorrect(ww_fraction / max_cw_ww, gamma);
382
419
  this->set_flag_(FLAG_HAS_COLD_WHITE, true);
383
420
  this->set_flag_(FLAG_HAS_WARM_WHITE, true);
384
421
  }
@@ -442,41 +479,39 @@ std::set<ColorMode> LightCall::get_suitable_color_modes_() {
442
479
  bool has_rgb = (this->has_color_brightness() && this->color_brightness_ > 0.0f) ||
443
480
  (this->has_red() || this->has_green() || this->has_blue());
444
481
 
482
+ // Build key from flags: [rgb][cwww][ct][white]
445
483
  #define KEY(white, ct, cwww, rgb) ((white) << 0 | (ct) << 1 | (cwww) << 2 | (rgb) << 3)
446
- #define ENTRY(white, ct, cwww, rgb, ...) \
447
- std::make_tuple<uint8_t, std::set<ColorMode>>(KEY(white, ct, cwww, rgb), __VA_ARGS__)
448
-
449
- // Flag order: white, color temperature, cwww, rgb
450
- std::array<std::tuple<uint8_t, std::set<ColorMode>>, 10> lookup_table{
451
- ENTRY(true, false, false, false,
452
- {ColorMode::WHITE, ColorMode::RGB_WHITE, ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::COLD_WARM_WHITE,
453
- ColorMode::RGB_COLD_WARM_WHITE}),
454
- ENTRY(false, true, false, false,
455
- {ColorMode::COLOR_TEMPERATURE, ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::COLD_WARM_WHITE,
456
- ColorMode::RGB_COLD_WARM_WHITE}),
457
- ENTRY(true, true, false, false,
458
- {ColorMode::COLD_WARM_WHITE, ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE}),
459
- ENTRY(false, false, true, false, {ColorMode::COLD_WARM_WHITE, ColorMode::RGB_COLD_WARM_WHITE}),
460
- ENTRY(false, false, false, false,
461
- {ColorMode::RGB_WHITE, ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE, ColorMode::RGB,
462
- ColorMode::WHITE, ColorMode::COLOR_TEMPERATURE, ColorMode::COLD_WARM_WHITE}),
463
- ENTRY(true, false, false, true,
464
- {ColorMode::RGB_WHITE, ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE}),
465
- ENTRY(false, true, false, true, {ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE}),
466
- ENTRY(true, true, false, true, {ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE}),
467
- ENTRY(false, false, true, true, {ColorMode::RGB_COLD_WARM_WHITE}),
468
- ENTRY(false, false, false, true,
469
- {ColorMode::RGB, ColorMode::RGB_WHITE, ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE}),
470
- };
471
-
472
- auto key = KEY(has_white, has_ct, has_cwww, has_rgb);
473
- for (auto &item : lookup_table) {
474
- if (std::get<0>(item) == key)
475
- return std::get<1>(item);
476
- }
477
-
478
- // This happens if there are conflicting flags given.
479
- return {};
484
+
485
+ uint8_t key = KEY(has_white, has_ct, has_cwww, has_rgb);
486
+
487
+ switch (key) {
488
+ case KEY(true, false, false, false): // white only
489
+ return {ColorMode::WHITE, ColorMode::RGB_WHITE, ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::COLD_WARM_WHITE,
490
+ ColorMode::RGB_COLD_WARM_WHITE};
491
+ case KEY(false, true, false, false): // ct only
492
+ return {ColorMode::COLOR_TEMPERATURE, ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::COLD_WARM_WHITE,
493
+ ColorMode::RGB_COLD_WARM_WHITE};
494
+ case KEY(true, true, false, false): // white + ct
495
+ return {ColorMode::COLD_WARM_WHITE, ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE};
496
+ case KEY(false, false, true, false): // cwww only
497
+ return {ColorMode::COLD_WARM_WHITE, ColorMode::RGB_COLD_WARM_WHITE};
498
+ case KEY(false, false, false, false): // none
499
+ return {ColorMode::RGB_WHITE, ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE, ColorMode::RGB,
500
+ ColorMode::WHITE, ColorMode::COLOR_TEMPERATURE, ColorMode::COLD_WARM_WHITE};
501
+ case KEY(true, false, false, true): // rgb + white
502
+ return {ColorMode::RGB_WHITE, ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE};
503
+ case KEY(false, true, false, true): // rgb + ct
504
+ case KEY(true, true, false, true): // rgb + white + ct
505
+ return {ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE};
506
+ case KEY(false, false, true, true): // rgb + cwww
507
+ return {ColorMode::RGB_COLD_WARM_WHITE};
508
+ case KEY(false, false, false, true): // rgb only
509
+ return {ColorMode::RGB, ColorMode::RGB_WHITE, ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE};
510
+ default:
511
+ return {}; // conflicting flags
512
+ }
513
+
514
+ #undef KEY
480
515
  }
481
516
 
482
517
  LightCall &LightCall::set_effect(const std::string &effect) {
@@ -84,18 +84,23 @@ class LightColorValues {
84
84
  * @return The linearly interpolated LightColorValues.
85
85
  */
86
86
  static LightColorValues lerp(const LightColorValues &start, const LightColorValues &end, float completion) {
87
+ // Directly interpolate the raw values to avoid getter/setter overhead.
88
+ // This is safe because:
89
+ // - All LightColorValues have their values clamped when set via the setters
90
+ // - std::lerp guarantees output is in the same range as inputs
91
+ // - Therefore the output doesn't need clamping, so we can skip the setters
87
92
  LightColorValues v;
88
- v.set_color_mode(end.color_mode_);
89
- v.set_state(std::lerp(start.get_state(), end.get_state(), completion));
90
- v.set_brightness(std::lerp(start.get_brightness(), end.get_brightness(), completion));
91
- v.set_color_brightness(std::lerp(start.get_color_brightness(), end.get_color_brightness(), completion));
92
- v.set_red(std::lerp(start.get_red(), end.get_red(), completion));
93
- v.set_green(std::lerp(start.get_green(), end.get_green(), completion));
94
- v.set_blue(std::lerp(start.get_blue(), end.get_blue(), completion));
95
- v.set_white(std::lerp(start.get_white(), end.get_white(), completion));
96
- v.set_color_temperature(std::lerp(start.get_color_temperature(), end.get_color_temperature(), completion));
97
- v.set_cold_white(std::lerp(start.get_cold_white(), end.get_cold_white(), completion));
98
- v.set_warm_white(std::lerp(start.get_warm_white(), end.get_warm_white(), completion));
93
+ v.color_mode_ = end.color_mode_;
94
+ v.state_ = std::lerp(start.state_, end.state_, completion);
95
+ v.brightness_ = std::lerp(start.brightness_, end.brightness_, completion);
96
+ v.color_brightness_ = std::lerp(start.color_brightness_, end.color_brightness_, completion);
97
+ v.red_ = std::lerp(start.red_, end.red_, completion);
98
+ v.green_ = std::lerp(start.green_, end.green_, completion);
99
+ v.blue_ = std::lerp(start.blue_, end.blue_, completion);
100
+ v.white_ = std::lerp(start.white_, end.white_, completion);
101
+ v.color_temperature_ = std::lerp(start.color_temperature_, end.color_temperature_, completion);
102
+ v.cold_white_ = std::lerp(start.cold_white_, end.cold_white_, completion);
103
+ v.warm_white_ = std::lerp(start.warm_white_, end.warm_white_, completion);
99
104
  return v;
100
105
  }
101
106
 
@@ -8,6 +8,32 @@ namespace light {
8
8
 
9
9
  // See https://www.home-assistant.io/integrations/light.mqtt/#json-schema for documentation on the schema
10
10
 
11
+ // Lookup table for color mode strings
12
+ static constexpr const char *get_color_mode_json_str(ColorMode mode) {
13
+ switch (mode) {
14
+ case ColorMode::ON_OFF:
15
+ return "onoff";
16
+ case ColorMode::BRIGHTNESS:
17
+ return "brightness";
18
+ case ColorMode::WHITE:
19
+ return "white"; // not supported by HA in MQTT
20
+ case ColorMode::COLOR_TEMPERATURE:
21
+ return "color_temp";
22
+ case ColorMode::COLD_WARM_WHITE:
23
+ return "cwww"; // not supported by HA
24
+ case ColorMode::RGB:
25
+ return "rgb";
26
+ case ColorMode::RGB_WHITE:
27
+ return "rgbw";
28
+ case ColorMode::RGB_COLOR_TEMPERATURE:
29
+ return "rgbct"; // not supported by HA
30
+ case ColorMode::RGB_COLD_WARM_WHITE:
31
+ return "rgbww";
32
+ default:
33
+ return nullptr;
34
+ }
35
+ }
36
+
11
37
  void LightJSONSchema::dump_json(LightState &state, JsonObject root) {
12
38
  // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson
13
39
  if (state.supports_effects())
@@ -16,60 +42,36 @@ void LightJSONSchema::dump_json(LightState &state, JsonObject root) {
16
42
  auto values = state.remote_values;
17
43
  auto traits = state.get_output()->get_traits();
18
44
 
19
- switch (values.get_color_mode()) {
20
- case ColorMode::UNKNOWN: // don't need to set color mode if we don't know it
21
- break;
22
- case ColorMode::ON_OFF:
23
- root["color_mode"] = "onoff";
24
- break;
25
- case ColorMode::BRIGHTNESS:
26
- root["color_mode"] = "brightness";
27
- break;
28
- case ColorMode::WHITE: // not supported by HA in MQTT
29
- root["color_mode"] = "white";
30
- break;
31
- case ColorMode::COLOR_TEMPERATURE:
32
- root["color_mode"] = "color_temp";
33
- break;
34
- case ColorMode::COLD_WARM_WHITE: // not supported by HA
35
- root["color_mode"] = "cwww";
36
- break;
37
- case ColorMode::RGB:
38
- root["color_mode"] = "rgb";
39
- break;
40
- case ColorMode::RGB_WHITE:
41
- root["color_mode"] = "rgbw";
42
- break;
43
- case ColorMode::RGB_COLOR_TEMPERATURE: // not supported by HA
44
- root["color_mode"] = "rgbct";
45
- break;
46
- case ColorMode::RGB_COLD_WARM_WHITE:
47
- root["color_mode"] = "rgbww";
48
- break;
45
+ const auto color_mode = values.get_color_mode();
46
+ const char *mode_str = get_color_mode_json_str(color_mode);
47
+ if (mode_str != nullptr) {
48
+ root["color_mode"] = mode_str;
49
49
  }
50
50
 
51
- if (values.get_color_mode() & ColorCapability::ON_OFF)
51
+ if (color_mode & ColorCapability::ON_OFF)
52
52
  root["state"] = (values.get_state() != 0.0f) ? "ON" : "OFF";
53
- if (values.get_color_mode() & ColorCapability::BRIGHTNESS)
54
- root["brightness"] = uint8_t(values.get_brightness() * 255);
53
+ if (color_mode & ColorCapability::BRIGHTNESS)
54
+ root["brightness"] = to_uint8_scale(values.get_brightness());
55
55
 
56
56
  JsonObject color = root["color"].to<JsonObject>();
57
- if (values.get_color_mode() & ColorCapability::RGB) {
58
- color["r"] = uint8_t(values.get_color_brightness() * values.get_red() * 255);
59
- color["g"] = uint8_t(values.get_color_brightness() * values.get_green() * 255);
60
- color["b"] = uint8_t(values.get_color_brightness() * values.get_blue() * 255);
57
+ if (color_mode & ColorCapability::RGB) {
58
+ float color_brightness = values.get_color_brightness();
59
+ color["r"] = to_uint8_scale(color_brightness * values.get_red());
60
+ color["g"] = to_uint8_scale(color_brightness * values.get_green());
61
+ color["b"] = to_uint8_scale(color_brightness * values.get_blue());
61
62
  }
62
- if (values.get_color_mode() & ColorCapability::WHITE) {
63
- color["w"] = uint8_t(values.get_white() * 255);
64
- root["white_value"] = uint8_t(values.get_white() * 255); // legacy API
63
+ if (color_mode & ColorCapability::WHITE) {
64
+ uint8_t white_val = to_uint8_scale(values.get_white());
65
+ color["w"] = white_val;
66
+ root["white_value"] = white_val; // legacy API
65
67
  }
66
- if (values.get_color_mode() & ColorCapability::COLOR_TEMPERATURE) {
68
+ if (color_mode & ColorCapability::COLOR_TEMPERATURE) {
67
69
  // this one isn't under the color subkey for some reason
68
70
  root["color_temp"] = uint32_t(values.get_color_temperature());
69
71
  }
70
- if (values.get_color_mode() & ColorCapability::COLD_WARM_WHITE) {
71
- color["c"] = uint8_t(values.get_cold_white() * 255);
72
- color["w"] = uint8_t(values.get_warm_white() * 255);
72
+ if (color_mode & ColorCapability::COLD_WARM_WHITE) {
73
+ color["c"] = to_uint8_scale(values.get_cold_white());
74
+ color["w"] = to_uint8_scale(values.get_warm_white());
73
75
  }
74
76
  }
75
77
 
@@ -18,15 +18,14 @@ LightCall LightState::toggle() { return this->make_call().set_state(!this->remot
18
18
  LightCall LightState::make_call() { return LightCall(this); }
19
19
 
20
20
  void LightState::setup() {
21
- ESP_LOGCONFIG(TAG, "Running setup for '%s'", this->get_name().c_str());
22
-
23
21
  this->output_->setup_state(this);
24
22
  for (auto *effect : this->effects_) {
25
23
  effect->init_internal(this);
26
24
  }
27
25
 
28
26
  // When supported color temperature range is known, initialize color temperature setting within bounds.
29
- float min_mireds = this->get_traits().get_min_mireds();
27
+ auto traits = this->get_traits();
28
+ float min_mireds = traits.get_min_mireds();
30
29
  if (min_mireds > 0) {
31
30
  this->remote_values.set_color_temperature(min_mireds);
32
31
  this->current_values.set_color_temperature(min_mireds);
@@ -45,11 +44,8 @@ void LightState::setup() {
45
44
  this->rtc_ = global_preferences->make_preference<LightStateRTCState>(this->get_object_id_hash());
46
45
  // Attempt to load from preferences, else fall back to default values
47
46
  if (!this->rtc_.load(&recovered)) {
48
- recovered.state = false;
49
- if (this->restore_mode_ == LIGHT_RESTORE_DEFAULT_ON ||
50
- this->restore_mode_ == LIGHT_RESTORE_INVERTED_DEFAULT_ON) {
51
- recovered.state = true;
52
- }
47
+ recovered.state = (this->restore_mode_ == LIGHT_RESTORE_DEFAULT_ON ||
48
+ this->restore_mode_ == LIGHT_RESTORE_INVERTED_DEFAULT_ON);
53
49
  } else if (this->restore_mode_ == LIGHT_RESTORE_INVERTED_DEFAULT_OFF ||
54
50
  this->restore_mode_ == LIGHT_RESTORE_INVERTED_DEFAULT_ON) {
55
51
  // Inverted restore state
@@ -90,17 +86,18 @@ void LightState::setup() {
90
86
  }
91
87
  void LightState::dump_config() {
92
88
  ESP_LOGCONFIG(TAG, "Light '%s'", this->get_name().c_str());
93
- if (this->get_traits().supports_color_capability(ColorCapability::BRIGHTNESS)) {
89
+ auto traits = this->get_traits();
90
+ if (traits.supports_color_capability(ColorCapability::BRIGHTNESS)) {
94
91
  ESP_LOGCONFIG(TAG,
95
92
  " Default Transition Length: %.1fs\n"
96
93
  " Gamma Correct: %.2f",
97
94
  this->default_transition_length_ / 1e3f, this->gamma_correct_);
98
95
  }
99
- if (this->get_traits().supports_color_capability(ColorCapability::COLOR_TEMPERATURE)) {
96
+ if (traits.supports_color_capability(ColorCapability::COLOR_TEMPERATURE)) {
100
97
  ESP_LOGCONFIG(TAG,
101
98
  " Min Mireds: %.1f\n"
102
99
  " Max Mireds: %.1f",
103
- this->get_traits().get_min_mireds(), this->get_traits().get_max_mireds());
100
+ traits.get_min_mireds(), traits.get_max_mireds());
104
101
  }
105
102
  }
106
103
  void LightState::loop() {
@@ -5,6 +5,13 @@
5
5
  #include <set>
6
6
 
7
7
  namespace esphome {
8
+
9
+ #ifdef USE_API
10
+ namespace api {
11
+ class APIConnection;
12
+ } // namespace api
13
+ #endif
14
+
8
15
  namespace light {
9
16
 
10
17
  /// This class is used to represent the capabilities of a light.
@@ -52,6 +59,16 @@ class LightTraits {
52
59
  void set_max_mireds(float max_mireds) { this->max_mireds_ = max_mireds; }
53
60
 
54
61
  protected:
62
+ #ifdef USE_API
63
+ // The API connection is a friend class to access internal methods
64
+ friend class api::APIConnection;
65
+ // This method returns a reference to the internal color modes set.
66
+ // It is used by the API to avoid copying data when encoding messages.
67
+ // Warning: Do not use this method outside of the API connection code.
68
+ // It returns a reference to internal data that can be invalidated.
69
+ const std::set<ColorMode> &get_supported_color_modes_for_api_() const { return this->supported_color_modes_; }
70
+ #endif
71
+
55
72
  std::set<ColorMode> supported_color_modes_{};
56
73
  float min_mireds_{0};
57
74
  float max_mireds_{0};
@@ -14,8 +14,6 @@ static const bool DEFAULT_INVERT = false;
14
14
  static const uint32_t DEFAULT_TICK = 330;
15
15
 
16
16
  void LightWaveRF::setup() {
17
- ESP_LOGCONFIG(TAG, "Running setup");
18
-
19
17
  this->lwtx_.lwtx_setup(pin_tx_, DEFAULT_REPEAT, DEFAULT_INVERT, DEFAULT_TICK);
20
18
  this->lwrx_.lwrx_setup(pin_rx_);
21
19
  }
@@ -24,7 +24,6 @@ static const uint8_t READ_TOUCH[1] = {0x07};
24
24
  }
25
25
 
26
26
  void LilygoT547Touchscreen::setup() {
27
- ESP_LOGCONFIG(TAG, "Running setup");
28
27
  this->interrupt_pin_->pin_mode(gpio::FLAG_INPUT | gpio::FLAG_PULLUP);
29
28
  this->interrupt_pin_->setup();
30
29
 
@@ -158,4 +158,3 @@ async def lock_is_off_to_code(config, condition_id, template_arg, args):
158
158
  @coroutine_with_priority(100.0)
159
159
  async def to_code(config):
160
160
  cg.add_global(lock_ns.using)
161
- cg.add_define("USE_LOCK")