esphome 2025.8.3__py3-none-any.whl → 2025.9.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 (345) hide show
  1. esphome/__main__.py +36 -42
  2. esphome/components/absolute_humidity/absolute_humidity.cpp +3 -5
  3. esphome/components/adc/adc_sensor_esp32.cpp +29 -6
  4. esphome/components/ags10/ags10.cpp +3 -18
  5. esphome/components/ags10/ags10.h +2 -12
  6. esphome/components/aht10/aht10.cpp +3 -3
  7. esphome/components/airthings_ble/__init__.py +2 -2
  8. esphome/components/alarm_control_panel/__init__.py +2 -2
  9. esphome/components/am2315c/am2315c.cpp +1 -17
  10. esphome/components/am2315c/am2315c.h +2 -3
  11. esphome/components/api/__init__.py +2 -2
  12. esphome/components/api/api_connection.cpp +34 -23
  13. esphome/components/api/api_connection.h +20 -39
  14. esphome/components/api/api_frame_helper.cpp +25 -25
  15. esphome/components/api/api_frame_helper.h +3 -3
  16. esphome/components/api/api_frame_helper_noise.cpp +75 -40
  17. esphome/components/api/api_frame_helper_noise.h +3 -7
  18. esphome/components/api/api_frame_helper_plaintext.cpp +17 -4
  19. esphome/components/api/api_frame_helper_plaintext.h +1 -4
  20. esphome/components/api/api_pb2.cpp +20 -2
  21. esphome/components/api/api_pb2.h +146 -141
  22. esphome/components/api/api_pb2_dump.cpp +12 -1
  23. esphome/components/api/proto.cpp +33 -37
  24. esphome/components/async_tcp/__init__.py +2 -2
  25. esphome/components/atm90e26/sensor.py +2 -0
  26. esphome/components/atm90e32/sensor.py +4 -2
  27. esphome/components/audio_adc/__init__.py +2 -2
  28. esphome/components/audio_dac/__init__.py +2 -2
  29. esphome/components/axs15231/touchscreen/axs15231_touchscreen.cpp +1 -1
  30. esphome/components/bedjet/bedjet_hub.cpp +1 -1
  31. esphome/components/binary_sensor/__init__.py +2 -2
  32. esphome/components/binary_sensor/binary_sensor.cpp +13 -0
  33. esphome/components/binary_sensor/binary_sensor.h +4 -7
  34. esphome/components/bl0940/__init__.py +6 -1
  35. esphome/components/bl0940/bl0940.cpp +178 -41
  36. esphome/components/bl0940/bl0940.h +121 -76
  37. esphome/components/bl0940/button/__init__.py +27 -0
  38. esphome/components/bl0940/button/calibration_reset_button.cpp +20 -0
  39. esphome/components/bl0940/button/calibration_reset_button.h +19 -0
  40. esphome/components/bl0940/number/__init__.py +94 -0
  41. esphome/components/bl0940/number/calibration_number.cpp +29 -0
  42. esphome/components/bl0940/number/calibration_number.h +26 -0
  43. esphome/components/bl0940/sensor.py +151 -2
  44. esphome/components/bl0942/bl0942.cpp +1 -1
  45. esphome/components/ble_client/output/__init__.py +4 -4
  46. esphome/components/bluetooth_proxy/__init__.py +1 -1
  47. esphome/components/bluetooth_proxy/bluetooth_connection.h +1 -1
  48. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +15 -7
  49. esphome/components/bluetooth_proxy/bluetooth_proxy.h +3 -2
  50. esphome/components/button/__init__.py +2 -2
  51. esphome/components/button/button.cpp +13 -0
  52. esphome/components/button/button.h +4 -7
  53. esphome/components/camera/buffer.h +18 -0
  54. esphome/components/camera/buffer_impl.cpp +20 -0
  55. esphome/components/camera/buffer_impl.h +26 -0
  56. esphome/components/camera/camera.h +43 -0
  57. esphome/components/camera/encoder.h +69 -0
  58. esphome/components/camera_encoder/__init__.py +62 -0
  59. esphome/components/camera_encoder/encoder_buffer_impl.cpp +23 -0
  60. esphome/components/camera_encoder/encoder_buffer_impl.h +25 -0
  61. esphome/components/camera_encoder/esp32_camera_jpeg_encoder.cpp +82 -0
  62. esphome/components/camera_encoder/esp32_camera_jpeg_encoder.h +39 -0
  63. esphome/components/captive_portal/__init__.py +2 -2
  64. esphome/components/captive_portal/captive_portal.cpp +35 -12
  65. esphome/components/captive_portal/captive_portal.h +3 -3
  66. esphome/components/ccs811/ccs811.cpp +3 -3
  67. esphome/components/climate/__init__.py +2 -2
  68. esphome/components/climate/climate.cpp +1 -1
  69. esphome/components/cover/__init__.py +5 -5
  70. esphome/components/cover/cover.cpp +1 -1
  71. esphome/components/cover/cover.h +2 -2
  72. esphome/components/dallas_temp/dallas_temp.cpp +2 -2
  73. esphome/components/datetime/__init__.py +2 -2
  74. esphome/components/datetime/date_entity.h +2 -2
  75. esphome/components/datetime/datetime_entity.h +2 -2
  76. esphome/components/datetime/time_entity.h +2 -2
  77. esphome/components/debug/debug_esp32.cpp +1 -1
  78. esphome/components/display/__init__.py +4 -4
  79. esphome/components/duty_time/duty_time_sensor.cpp +1 -1
  80. esphome/components/esp32/__init__.py +0 -5
  81. esphome/components/esp32/gpio.cpp +27 -23
  82. esphome/components/esp32/gpio.h +26 -11
  83. esphome/components/esp32/preferences.cpp +8 -4
  84. esphome/components/esp32_ble/__init__.py +7 -2
  85. esphome/components/esp32_ble_client/ble_client_base.cpp +7 -3
  86. esphome/components/esp32_ble_tracker/__init__.py +2 -2
  87. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +9 -44
  88. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +2 -14
  89. esphome/components/esp8266/__init__.py +2 -2
  90. esphome/components/esp8266/core.cpp +2 -2
  91. esphome/components/esp8266/gpio.py +4 -4
  92. esphome/components/esp8266/preferences.cpp +30 -28
  93. esphome/components/esphome/ota/__init__.py +2 -2
  94. esphome/components/esphome/ota/ota_esphome.cpp +21 -19
  95. esphome/components/esphome/ota/ota_esphome.h +6 -5
  96. esphome/components/ethernet/__init__.py +7 -2
  97. esphome/components/ethernet/ethernet_component.cpp +1 -1
  98. esphome/components/event/__init__.py +2 -2
  99. esphome/components/event/event.h +4 -4
  100. esphome/components/fan/__init__.py +2 -2
  101. esphome/components/fan/fan.cpp +2 -1
  102. esphome/components/gdk101/gdk101.cpp +4 -4
  103. esphome/components/globals/__init__.py +2 -2
  104. esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp +19 -18
  105. esphome/components/gpio_expander/cached_gpio.h +36 -16
  106. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.cpp +5 -5
  107. esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +1 -1
  108. esphome/components/haier/haier_base.cpp +1 -1
  109. esphome/components/haier/hon_climate.cpp +1 -1
  110. esphome/components/hlw8012/hlw8012.cpp +5 -5
  111. esphome/components/honeywellabp2_i2c/honeywellabp2.cpp +4 -4
  112. esphome/components/host/preferences.h +3 -2
  113. esphome/components/hte501/hte501.cpp +3 -21
  114. esphome/components/hte501/hte501.h +2 -3
  115. esphome/components/http_request/ota/__init__.py +2 -2
  116. esphome/components/i2c/__init__.py +2 -2
  117. esphome/components/i2c/i2c.cpp +13 -9
  118. esphome/components/i2c/i2c_bus.h +36 -6
  119. esphome/components/i2s_audio/__init__.py +8 -2
  120. esphome/components/i2s_audio/media_player/__init__.py +1 -1
  121. esphome/components/i2s_audio/microphone/__init__.py +1 -1
  122. esphome/components/i2s_audio/speaker/__init__.py +1 -1
  123. esphome/components/inkplate/__init__.py +1 -0
  124. esphome/components/inkplate/const.py +105 -0
  125. esphome/components/inkplate/display.py +238 -0
  126. esphome/components/{inkplate6 → inkplate}/inkplate.cpp +156 -74
  127. esphome/components/{inkplate6 → inkplate}/inkplate.h +28 -68
  128. esphome/components/inkplate6/__init__.py +0 -1
  129. esphome/components/inkplate6/display.py +2 -211
  130. esphome/components/integration/integration_sensor.cpp +1 -1
  131. esphome/components/json/__init__.py +2 -2
  132. esphome/components/kmeteriso/kmeteriso.cpp +1 -1
  133. esphome/components/lc709203f/lc709203f.cpp +4 -17
  134. esphome/components/lc709203f/lc709203f.h +2 -3
  135. esphome/components/ld2420/text_sensor/{text_sensor.cpp → ld2420_text_sensor.cpp} +1 -1
  136. esphome/components/ld2450/ld2450.cpp +1 -1
  137. esphome/components/libretiny/preferences.cpp +13 -5
  138. esphome/components/light/__init__.py +2 -2
  139. esphome/components/light/addressable_light_effect.h +7 -0
  140. esphome/components/light/base_light_effects.h +8 -0
  141. esphome/components/light/light_call.cpp +22 -20
  142. esphome/components/light/light_effect.cpp +36 -0
  143. esphome/components/light/light_effect.h +14 -0
  144. esphome/components/light/light_json_schema.cpp +9 -1
  145. esphome/components/light/light_state.cpp +2 -2
  146. esphome/components/light/light_state.h +39 -0
  147. esphome/components/lock/__init__.py +2 -2
  148. esphome/components/lock/lock.h +2 -2
  149. esphome/components/logger/__init__.py +2 -2
  150. esphome/components/logger/logger.cpp +25 -4
  151. esphome/components/logger/logger.h +1 -1
  152. esphome/components/logger/logger_esp32.cpp +16 -8
  153. esphome/components/logger/logger_esp8266.cpp +11 -3
  154. esphome/components/logger/logger_libretiny.cpp +13 -3
  155. esphome/components/logger/logger_rp2040.cpp +14 -3
  156. esphome/components/logger/logger_zephyr.cpp +15 -4
  157. esphome/components/lvgl/defines.py +1 -0
  158. esphome/components/lvgl/hello_world.py +96 -33
  159. esphome/components/lvgl/number/lvgl_number.h +1 -1
  160. esphome/components/lvgl/select/lvgl_select.h +1 -1
  161. esphome/components/lvgl/widgets/__init__.py +0 -1
  162. esphome/components/lvgl/widgets/spinbox.py +20 -11
  163. esphome/components/m5stack_8angle/binary_sensor/m5stack_8angle_binary_sensor.cpp +1 -1
  164. esphome/components/m5stack_8angle/sensor/m5stack_8angle_sensor.cpp +1 -1
  165. esphome/components/mapping/__init__.py +13 -5
  166. esphome/components/mapping/mapping.h +69 -0
  167. esphome/components/max17043/max17043.cpp +2 -2
  168. esphome/components/mcp23016/__init__.py +1 -0
  169. esphome/components/mcp23016/mcp23016.cpp +20 -5
  170. esphome/components/mcp23016/mcp23016.h +10 -4
  171. esphome/components/mcp23x08_base/mcp23x08_base.cpp +1 -1
  172. esphome/components/mcp23x17_base/mcp23x17_base.cpp +2 -2
  173. esphome/components/mdns/__init__.py +2 -2
  174. esphome/components/mdns/mdns_component.cpp +145 -54
  175. esphome/components/media_player/__init__.py +2 -2
  176. esphome/components/micro_wake_word/__init__.py +2 -2
  177. esphome/components/microphone/__init__.py +2 -2
  178. esphome/components/mipi/__init__.py +77 -33
  179. esphome/components/mipi_rgb/__init__.py +2 -0
  180. esphome/components/mipi_rgb/display.py +321 -0
  181. esphome/components/mipi_rgb/mipi_rgb.cpp +388 -0
  182. esphome/components/mipi_rgb/mipi_rgb.h +127 -0
  183. esphome/components/mipi_rgb/models/guition.py +24 -0
  184. esphome/components/mipi_rgb/models/lilygo.py +228 -0
  185. esphome/components/mipi_rgb/models/rpi.py +9 -0
  186. esphome/components/mipi_rgb/models/st7701s.py +214 -0
  187. esphome/components/mipi_rgb/models/waveshare.py +64 -0
  188. esphome/components/mipi_spi/models/jc.py +229 -0
  189. esphome/components/mlx90614/mlx90614.cpp +1 -16
  190. esphome/components/mlx90614/mlx90614.h +0 -1
  191. esphome/components/mqtt/__init__.py +2 -2
  192. esphome/components/mqtt/mqtt_sensor.cpp +7 -2
  193. esphome/components/ms5611/ms5611.cpp +7 -6
  194. esphome/components/network/__init__.py +2 -2
  195. esphome/components/nextion/nextion_upload.cpp +4 -1
  196. esphome/components/nrf52/__init__.py +49 -6
  197. esphome/components/nrf52/const.py +1 -0
  198. esphome/components/nrf52/dfu.cpp +51 -0
  199. esphome/components/nrf52/dfu.h +24 -0
  200. esphome/components/ntc/ntc.cpp +1 -1
  201. esphome/components/number/__init__.py +2 -2
  202. esphome/components/number/automation.cpp +1 -1
  203. esphome/components/number/number.cpp +21 -0
  204. esphome/components/number/number.h +4 -13
  205. esphome/components/opentherm/hub.h +6 -6
  206. esphome/components/opentherm/number/{number.cpp → opentherm_number.cpp} +2 -2
  207. esphome/components/opentherm/output/{output.cpp → opentherm_output.cpp} +1 -1
  208. esphome/components/opentherm/switch/{switch.cpp → opentherm_switch.cpp} +1 -1
  209. esphome/components/ota/__init__.py +2 -2
  210. esphome/components/pca6416a/__init__.py +1 -0
  211. esphome/components/pca6416a/pca6416a.cpp +20 -5
  212. esphome/components/pca6416a/pca6416a.h +12 -5
  213. esphome/components/pca9554/__init__.py +2 -1
  214. esphome/components/pca9554/pca9554.cpp +12 -18
  215. esphome/components/pca9554/pca9554.h +10 -9
  216. esphome/components/pcf8574/__init__.py +1 -0
  217. esphome/components/pcf8574/pcf8574.cpp +14 -5
  218. esphome/components/pcf8574/pcf8574.h +13 -6
  219. esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +7 -7
  220. esphome/components/pipsolar/__init__.py +3 -3
  221. esphome/components/pipsolar/output/__init__.py +4 -4
  222. esphome/components/pulse_width/pulse_width.cpp +2 -2
  223. esphome/components/qmp6988/qmp6988.cpp +81 -126
  224. esphome/components/qmp6988/qmp6988.h +31 -37
  225. esphome/components/radon_eye_ble/__init__.py +2 -2
  226. esphome/components/remote_base/__init__.py +6 -8
  227. esphome/components/rotary_encoder/rotary_encoder.cpp +1 -1
  228. esphome/components/rp2040/__init__.py +2 -2
  229. esphome/components/runtime_stats/runtime_stats.cpp +10 -23
  230. esphome/components/runtime_stats/runtime_stats.h +4 -10
  231. esphome/components/safe_mode/__init__.py +2 -2
  232. esphome/components/safe_mode/safe_mode.cpp +33 -31
  233. esphome/components/script/script.cpp +6 -0
  234. esphome/components/script/script.h +19 -5
  235. esphome/components/sdm_meter/sensor.py +3 -1
  236. esphome/components/select/__init__.py +2 -2
  237. esphome/components/select/select.h +2 -2
  238. esphome/components/sen5x/sen5x.cpp +58 -55
  239. esphome/components/sen5x/sen5x.h +21 -15
  240. esphome/components/sen5x/sensor.py +67 -44
  241. esphome/components/sensirion_common/i2c_sensirion.cpp +18 -47
  242. esphome/components/sensirion_common/i2c_sensirion.h +39 -55
  243. esphome/components/sensor/__init__.py +2 -2
  244. esphome/components/sensor/automation.h +1 -1
  245. esphome/components/sensor/sensor.cpp +34 -6
  246. esphome/components/sensor/sensor.h +4 -21
  247. esphome/components/sgp30/sgp30.cpp +34 -35
  248. esphome/components/sgp30/sgp30.h +11 -10
  249. esphome/components/sgp4x/sgp4x.cpp +2 -2
  250. esphome/components/shelly_dimmer/light.py +7 -7
  251. esphome/components/sht4x/sht4x.cpp +1 -1
  252. esphome/components/sntp/sntp_component.cpp +36 -9
  253. esphome/components/sntp/sntp_component.h +7 -0
  254. esphome/components/sound_level/sound_level.cpp +1 -1
  255. esphome/components/speaker/__init__.py +2 -2
  256. esphome/components/speaker/media_player/__init__.py +2 -2
  257. esphome/components/speaker/media_player/speaker_media_player.cpp +1 -1
  258. esphome/components/spi/__init__.py +2 -2
  259. esphome/components/sprinkler/sprinkler.cpp +1 -1
  260. esphome/components/sps30/sps30.cpp +18 -23
  261. esphome/components/sps30/sps30.h +3 -3
  262. esphome/components/status_led/__init__.py +2 -2
  263. esphome/components/stepper/__init__.py +2 -2
  264. esphome/components/switch/__init__.py +2 -2
  265. esphome/components/switch/switch.cpp +5 -5
  266. esphome/components/sx1509/__init__.py +1 -1
  267. esphome/components/sx1509/sx1509.cpp +12 -7
  268. esphome/components/sx1509/sx1509.h +11 -4
  269. esphome/components/tca9555/tca9555.cpp +5 -5
  270. esphome/components/tee501/tee501.cpp +2 -21
  271. esphome/components/tee501/tee501.h +2 -4
  272. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +1 -1
  273. esphome/components/template/datetime/template_date.cpp +1 -1
  274. esphome/components/template/datetime/template_datetime.cpp +2 -2
  275. esphome/components/template/datetime/template_time.cpp +1 -1
  276. esphome/components/template/number/template_number.cpp +1 -1
  277. esphome/components/template/select/template_select.cpp +1 -1
  278. esphome/components/template/text/template_text.cpp +1 -1
  279. esphome/components/text/__init__.py +2 -2
  280. esphome/components/text/text.h +2 -2
  281. esphome/components/text_sensor/__init__.py +2 -2
  282. esphome/components/text_sensor/text_sensor.h +4 -4
  283. esphome/components/thermostat/climate.py +11 -7
  284. esphome/components/thermostat/thermostat_climate.cpp +237 -206
  285. esphome/components/thermostat/thermostat_climate.h +52 -41
  286. esphome/components/time/__init__.py +2 -2
  287. esphome/components/tmp1075/tmp1075.cpp +1 -1
  288. esphome/components/total_daily_energy/total_daily_energy.cpp +1 -1
  289. esphome/components/touchscreen/__init__.py +2 -2
  290. esphome/components/tuya/number/tuya_number.cpp +1 -1
  291. esphome/components/udp/udp_component.cpp +3 -3
  292. esphome/components/ufire_ec/ufire_ec.cpp +4 -4
  293. esphome/components/ufire_ise/ufire_ise.cpp +4 -4
  294. esphome/components/update/__init__.py +2 -2
  295. esphome/components/usb_uart/usb_uart.cpp +1 -1
  296. esphome/components/valve/__init__.py +5 -5
  297. esphome/components/valve/valve.cpp +1 -1
  298. esphome/components/valve/valve.h +2 -2
  299. esphome/components/wake_on_lan/wake_on_lan.cpp +2 -2
  300. esphome/components/waveshare_epaper/waveshare_213v3.cpp +1 -1
  301. esphome/components/web_server/__init__.py +2 -2
  302. esphome/components/web_server/ota/__init__.py +2 -2
  303. esphome/components/web_server/ota/ota_web_server.cpp +11 -0
  304. esphome/components/web_server/web_server.cpp +58 -12
  305. esphome/components/web_server_base/__init__.py +2 -2
  306. esphome/components/wifi/__init__.py +5 -5
  307. esphome/components/wifi/wifi_component.cpp +3 -3
  308. esphome/components/wifi/wifi_component_esp_idf.cpp +2 -0
  309. esphome/config_validation.py +2 -2
  310. esphome/const.py +2 -1
  311. esphome/core/__init__.py +1 -0
  312. esphome/core/application.cpp +89 -51
  313. esphome/core/application.h +1 -0
  314. esphome/core/component.cpp +41 -19
  315. esphome/core/component.h +17 -13
  316. esphome/core/config.py +7 -7
  317. esphome/core/defines.h +4 -0
  318. esphome/core/entity_base.cpp +22 -8
  319. esphome/core/entity_base.h +43 -0
  320. esphome/core/helpers.cpp +26 -13
  321. esphome/core/helpers.h +4 -3
  322. esphome/core/ring_buffer.cpp +6 -2
  323. esphome/core/ring_buffer.h +2 -1
  324. esphome/core/scheduler.cpp +175 -94
  325. esphome/core/scheduler.h +66 -35
  326. esphome/core/time.cpp +6 -20
  327. esphome/coroutine.py +80 -3
  328. esphome/cpp_generator.py +13 -0
  329. esphome/cpp_helpers.py +2 -2
  330. esphome/dashboard/web_server.py +67 -10
  331. esphome/espota2.py +13 -6
  332. esphome/helpers.py +68 -83
  333. esphome/resolver.py +67 -0
  334. esphome/util.py +9 -6
  335. esphome/wizard.py +39 -26
  336. {esphome-2025.8.3.dist-info → esphome-2025.9.0b1.dist-info}/METADATA +9 -9
  337. {esphome-2025.8.3.dist-info → esphome-2025.9.0b1.dist-info}/RECORD +345 -314
  338. /esphome/components/ld2420/text_sensor/{text_sensor.h → ld2420_text_sensor.h} +0 -0
  339. /esphome/components/opentherm/number/{number.h → opentherm_number.h} +0 -0
  340. /esphome/components/opentherm/output/{output.h → opentherm_output.h} +0 -0
  341. /esphome/components/opentherm/switch/{switch.h → opentherm_switch.h} +0 -0
  342. {esphome-2025.8.3.dist-info → esphome-2025.9.0b1.dist-info}/WHEEL +0 -0
  343. {esphome-2025.8.3.dist-info → esphome-2025.9.0b1.dist-info}/entry_points.txt +0 -0
  344. {esphome-2025.8.3.dist-info → esphome-2025.9.0b1.dist-info}/licenses/LICENSE +0 -0
  345. {esphome-2025.8.3.dist-info → esphome-2025.9.0b1.dist-info}/top_level.txt +0 -0
@@ -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;
@@ -12,6 +12,7 @@
12
12
  #include "light_transformer.h"
13
13
 
14
14
  #include <vector>
15
+ #include <strings.h>
15
16
 
16
17
  namespace esphome {
17
18
  namespace light {
@@ -163,6 +164,44 @@ class LightState : public EntityBase, public Component {
163
164
  /// Add effects for this light state.
164
165
  void add_effects(const std::vector<LightEffect *> &effects);
165
166
 
167
+ /// Get the total number of effects available for this light.
168
+ size_t get_effect_count() const { return this->effects_.size(); }
169
+
170
+ /// Get the currently active effect index (0 = no effect, 1+ = effect index).
171
+ uint32_t get_current_effect_index() const { return this->active_effect_index_; }
172
+
173
+ /// Get effect index by name. Returns 0 if effect not found.
174
+ uint32_t get_effect_index(const std::string &effect_name) const {
175
+ if (strcasecmp(effect_name.c_str(), "none") == 0) {
176
+ return 0;
177
+ }
178
+ for (size_t i = 0; i < this->effects_.size(); i++) {
179
+ if (strcasecmp(effect_name.c_str(), this->effects_[i]->get_name().c_str()) == 0) {
180
+ return i + 1; // Effects are 1-indexed in active_effect_index_
181
+ }
182
+ }
183
+ return 0; // Effect not found
184
+ }
185
+
186
+ /// Get effect by index. Returns nullptr if index is invalid.
187
+ LightEffect *get_effect_by_index(uint32_t index) const {
188
+ if (index == 0 || index > this->effects_.size()) {
189
+ return nullptr;
190
+ }
191
+ return this->effects_[index - 1]; // Effects are 1-indexed in active_effect_index_
192
+ }
193
+
194
+ /// Get effect name by index. Returns "None" for index 0, empty string for invalid index.
195
+ std::string get_effect_name_by_index(uint32_t index) const {
196
+ if (index == 0) {
197
+ return "None";
198
+ }
199
+ if (index > this->effects_.size()) {
200
+ return ""; // Invalid index
201
+ }
202
+ return this->effects_[index - 1]->get_name();
203
+ }
204
+
166
205
  /// The result of all the current_values_as_* methods have gamma correction applied.
167
206
  void current_values_as_binary(bool *binary);
168
207
 
@@ -13,7 +13,7 @@ from esphome.const import (
13
13
  CONF_TRIGGER_ID,
14
14
  CONF_WEB_SERVER,
15
15
  )
16
- from esphome.core import CORE, coroutine_with_priority
16
+ from esphome.core import CORE, CoroPriority, coroutine_with_priority
17
17
  from esphome.core.entity_helpers import entity_duplicate_validator, setup_entity
18
18
  from esphome.cpp_generator import MockObjClass
19
19
 
@@ -155,6 +155,6 @@ async def lock_is_off_to_code(config, condition_id, template_arg, args):
155
155
  return cg.new_Pvariable(condition_id, template_arg, paren, False)
156
156
 
157
157
 
158
- @coroutine_with_priority(100.0)
158
+ @coroutine_with_priority(CoroPriority.CORE)
159
159
  async def to_code(config):
160
160
  cg.add_global(lock_ns.using)
@@ -15,8 +15,8 @@ class Lock;
15
15
  #define LOG_LOCK(prefix, type, obj) \
16
16
  if ((obj) != nullptr) { \
17
17
  ESP_LOGCONFIG(TAG, "%s%s '%s'", prefix, LOG_STR_LITERAL(type), (obj)->get_name().c_str()); \
18
- if (!(obj)->get_icon().empty()) { \
19
- ESP_LOGCONFIG(TAG, "%s Icon: '%s'", prefix, (obj)->get_icon().c_str()); \
18
+ if (!(obj)->get_icon_ref().empty()) { \
19
+ ESP_LOGCONFIG(TAG, "%s Icon: '%s'", prefix, (obj)->get_icon_ref().c_str()); \
20
20
  } \
21
21
  if ((obj)->traits.get_assumed_state()) { \
22
22
  ESP_LOGCONFIG(TAG, "%s Assumed State: YES", prefix); \
@@ -51,7 +51,7 @@ from esphome.const import (
51
51
  PLATFORM_RTL87XX,
52
52
  PlatformFramework,
53
53
  )
54
- from esphome.core import CORE, Lambda, coroutine_with_priority
54
+ from esphome.core import CORE, CoroPriority, Lambda, coroutine_with_priority
55
55
 
56
56
  CODEOWNERS = ["@esphome/core"]
57
57
  logger_ns = cg.esphome_ns.namespace("logger")
@@ -275,7 +275,7 @@ CONFIG_SCHEMA = cv.All(
275
275
  )
276
276
 
277
277
 
278
- @coroutine_with_priority(90.0)
278
+ @coroutine_with_priority(CoroPriority.DIAGNOSTICS)
279
279
  async def to_code(config):
280
280
  baud_rate = config[CONF_BAUD_RATE]
281
281
  level = config[CONF_LEVEL]
@@ -246,19 +246,40 @@ void Logger::add_on_log_callback(std::function<void(uint8_t, const char *, const
246
246
  this->log_callback_.add(std::move(callback));
247
247
  }
248
248
  float Logger::get_setup_priority() const { return setup_priority::BUS + 500.0f; }
249
+
250
+ #ifdef USE_STORE_LOG_STR_IN_FLASH
251
+ // ESP8266: PSTR() cannot be used in array initializers, so we need to declare
252
+ // each string separately as a global constant first
253
+ static const char LOG_LEVEL_NONE[] PROGMEM = "NONE";
254
+ static const char LOG_LEVEL_ERROR[] PROGMEM = "ERROR";
255
+ static const char LOG_LEVEL_WARN[] PROGMEM = "WARN";
256
+ static const char LOG_LEVEL_INFO[] PROGMEM = "INFO";
257
+ static const char LOG_LEVEL_CONFIG[] PROGMEM = "CONFIG";
258
+ static const char LOG_LEVEL_DEBUG[] PROGMEM = "DEBUG";
259
+ static const char LOG_LEVEL_VERBOSE[] PROGMEM = "VERBOSE";
260
+ static const char LOG_LEVEL_VERY_VERBOSE[] PROGMEM = "VERY_VERBOSE";
261
+
262
+ static const LogString *const LOG_LEVELS[] = {
263
+ reinterpret_cast<const LogString *>(LOG_LEVEL_NONE), reinterpret_cast<const LogString *>(LOG_LEVEL_ERROR),
264
+ reinterpret_cast<const LogString *>(LOG_LEVEL_WARN), reinterpret_cast<const LogString *>(LOG_LEVEL_INFO),
265
+ reinterpret_cast<const LogString *>(LOG_LEVEL_CONFIG), reinterpret_cast<const LogString *>(LOG_LEVEL_DEBUG),
266
+ reinterpret_cast<const LogString *>(LOG_LEVEL_VERBOSE), reinterpret_cast<const LogString *>(LOG_LEVEL_VERY_VERBOSE),
267
+ };
268
+ #else
249
269
  static const char *const LOG_LEVELS[] = {"NONE", "ERROR", "WARN", "INFO", "CONFIG", "DEBUG", "VERBOSE", "VERY_VERBOSE"};
270
+ #endif
250
271
 
251
272
  void Logger::dump_config() {
252
273
  ESP_LOGCONFIG(TAG,
253
274
  "Logger:\n"
254
275
  " Max Level: %s\n"
255
276
  " Initial Level: %s",
256
- LOG_LEVELS[ESPHOME_LOG_LEVEL], LOG_LEVELS[this->current_level_]);
277
+ LOG_STR_ARG(LOG_LEVELS[ESPHOME_LOG_LEVEL]), LOG_STR_ARG(LOG_LEVELS[this->current_level_]));
257
278
  #ifndef USE_HOST
258
279
  ESP_LOGCONFIG(TAG,
259
280
  " Log Baud Rate: %" PRIu32 "\n"
260
281
  " Hardware UART: %s",
261
- this->baud_rate_, get_uart_selection_());
282
+ this->baud_rate_, LOG_STR_ARG(get_uart_selection_()));
262
283
  #endif
263
284
  #ifdef USE_ESPHOME_TASK_LOG_BUFFER
264
285
  if (this->log_buffer_) {
@@ -267,14 +288,14 @@ void Logger::dump_config() {
267
288
  #endif
268
289
 
269
290
  for (auto &it : this->log_levels_) {
270
- ESP_LOGCONFIG(TAG, " Level for '%s': %s", it.first.c_str(), LOG_LEVELS[it.second]);
291
+ ESP_LOGCONFIG(TAG, " Level for '%s': %s", it.first.c_str(), LOG_STR_ARG(LOG_LEVELS[it.second]));
271
292
  }
272
293
  }
273
294
 
274
295
  void Logger::set_log_level(uint8_t level) {
275
296
  if (level > ESPHOME_LOG_LEVEL) {
276
297
  level = ESPHOME_LOG_LEVEL;
277
- ESP_LOGW(TAG, "Cannot set log level higher than pre-compiled %s", LOG_LEVELS[ESPHOME_LOG_LEVEL]);
298
+ ESP_LOGW(TAG, "Cannot set log level higher than pre-compiled %s", LOG_STR_ARG(LOG_LEVELS[ESPHOME_LOG_LEVEL]));
278
299
  }
279
300
  this->current_level_ = level;
280
301
  this->level_callback_.call(level);
@@ -226,7 +226,7 @@ class Logger : public Component {
226
226
  }
227
227
 
228
228
  #ifndef USE_HOST
229
- const char *get_uart_selection_();
229
+ const LogString *get_uart_selection_();
230
230
  #endif
231
231
 
232
232
  // Group 4-byte aligned members first
@@ -190,20 +190,28 @@ void HOT Logger::write_msg_(const char *msg) {
190
190
  void HOT Logger::write_msg_(const char *msg) { this->hw_serial_->println(msg); }
191
191
  #endif
192
192
 
193
- const char *const UART_SELECTIONS[] = {
194
- "UART0", "UART1",
193
+ const LogString *Logger::get_uart_selection_() {
194
+ switch (this->uart_) {
195
+ case UART_SELECTION_UART0:
196
+ return LOG_STR("UART0");
197
+ case UART_SELECTION_UART1:
198
+ return LOG_STR("UART1");
195
199
  #ifdef USE_ESP32_VARIANT_ESP32
196
- "UART2",
200
+ case UART_SELECTION_UART2:
201
+ return LOG_STR("UART2");
197
202
  #endif
198
203
  #ifdef USE_LOGGER_USB_CDC
199
- "USB_CDC",
204
+ case UART_SELECTION_USB_CDC:
205
+ return LOG_STR("USB_CDC");
200
206
  #endif
201
207
  #ifdef USE_LOGGER_USB_SERIAL_JTAG
202
- "USB_SERIAL_JTAG",
208
+ case UART_SELECTION_USB_SERIAL_JTAG:
209
+ return LOG_STR("USB_SERIAL_JTAG");
203
210
  #endif
204
- };
205
-
206
- const char *Logger::get_uart_selection_() { return UART_SELECTIONS[this->uart_]; }
211
+ default:
212
+ return LOG_STR("UNKNOWN");
213
+ }
214
+ }
207
215
 
208
216
  } // namespace esphome::logger
209
217
  #endif
@@ -35,9 +35,17 @@ void Logger::pre_setup() {
35
35
 
36
36
  void HOT Logger::write_msg_(const char *msg) { this->hw_serial_->println(msg); }
37
37
 
38
- const char *const UART_SELECTIONS[] = {"UART0", "UART1", "UART0_SWAP"};
39
-
40
- const char *Logger::get_uart_selection_() { return UART_SELECTIONS[this->uart_]; }
38
+ const LogString *Logger::get_uart_selection_() {
39
+ switch (this->uart_) {
40
+ case UART_SELECTION_UART0:
41
+ return LOG_STR("UART0");
42
+ case UART_SELECTION_UART1:
43
+ return LOG_STR("UART1");
44
+ case UART_SELECTION_UART0_SWAP:
45
+ default:
46
+ return LOG_STR("UART0_SWAP");
47
+ }
48
+ }
41
49
 
42
50
  } // namespace esphome::logger
43
51
  #endif
@@ -51,9 +51,19 @@ void Logger::pre_setup() {
51
51
 
52
52
  void HOT Logger::write_msg_(const char *msg) { this->hw_serial_->println(msg); }
53
53
 
54
- const char *const UART_SELECTIONS[] = {"DEFAULT", "UART0", "UART1", "UART2"};
55
-
56
- const char *Logger::get_uart_selection_() { return UART_SELECTIONS[this->uart_]; }
54
+ const LogString *Logger::get_uart_selection_() {
55
+ switch (this->uart_) {
56
+ case UART_SELECTION_DEFAULT:
57
+ return LOG_STR("DEFAULT");
58
+ case UART_SELECTION_UART0:
59
+ return LOG_STR("UART0");
60
+ case UART_SELECTION_UART1:
61
+ return LOG_STR("UART1");
62
+ case UART_SELECTION_UART2:
63
+ default:
64
+ return LOG_STR("UART2");
65
+ }
66
+ }
57
67
 
58
68
  } // namespace esphome::logger
59
69
 
@@ -29,9 +29,20 @@ void Logger::pre_setup() {
29
29
 
30
30
  void HOT Logger::write_msg_(const char *msg) { this->hw_serial_->println(msg); }
31
31
 
32
- const char *const UART_SELECTIONS[] = {"UART0", "UART1", "USB_CDC"};
33
-
34
- const char *Logger::get_uart_selection_() { return UART_SELECTIONS[this->uart_]; }
32
+ const LogString *Logger::get_uart_selection_() {
33
+ switch (this->uart_) {
34
+ case UART_SELECTION_UART0:
35
+ return LOG_STR("UART0");
36
+ case UART_SELECTION_UART1:
37
+ return LOG_STR("UART1");
38
+ #ifdef USE_LOGGER_USB_CDC
39
+ case UART_SELECTION_USB_CDC:
40
+ return LOG_STR("USB_CDC");
41
+ #endif
42
+ default:
43
+ return LOG_STR("UNKNOWN");
44
+ }
45
+ }
35
46
 
36
47
  } // namespace esphome::logger
37
48
  #endif // USE_RP2040
@@ -54,7 +54,7 @@ void Logger::pre_setup() {
54
54
  #endif
55
55
  }
56
56
  if (!device_is_ready(uart_dev)) {
57
- ESP_LOGE(TAG, "%s is not ready.", get_uart_selection_());
57
+ ESP_LOGE(TAG, "%s is not ready.", LOG_STR_ARG(get_uart_selection_()));
58
58
  } else {
59
59
  this->uart_dev_ = uart_dev;
60
60
  }
@@ -77,9 +77,20 @@ void HOT Logger::write_msg_(const char *msg) {
77
77
  uart_poll_out(this->uart_dev_, '\n');
78
78
  }
79
79
 
80
- const char *const UART_SELECTIONS[] = {"UART0", "UART1", "USB_CDC"};
81
-
82
- const char *Logger::get_uart_selection_() { return UART_SELECTIONS[this->uart_]; }
80
+ const LogString *Logger::get_uart_selection_() {
81
+ switch (this->uart_) {
82
+ case UART_SELECTION_UART0:
83
+ return LOG_STR("UART0");
84
+ case UART_SELECTION_UART1:
85
+ return LOG_STR("UART1");
86
+ #ifdef USE_LOGGER_USB_CDC
87
+ case UART_SELECTION_USB_CDC:
88
+ return LOG_STR("USB_CDC");
89
+ #endif
90
+ default:
91
+ return LOG_STR("UNKNOWN");
92
+ }
93
+ }
83
94
 
84
95
  } // namespace esphome::logger
85
96
 
@@ -451,6 +451,7 @@ CONF_GRID_ROWS = "grid_rows"
451
451
  CONF_HEADER_MODE = "header_mode"
452
452
  CONF_HOME = "home"
453
453
  CONF_INITIAL_FOCUS = "initial_focus"
454
+ CONF_SELECTED_DIGIT = "selected_digit"
454
455
  CONF_KEY_CODE = "key_code"
455
456
  CONF_KEYPADS = "keypads"
456
457
  CONF_LAYOUT = "layout"