esphome 2025.9.2__py3-none-any.whl → 2025.10.0b1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (344) hide show
  1. esphome/__main__.py +87 -31
  2. esphome/address_cache.py +142 -0
  3. esphome/automation.py +130 -32
  4. esphome/build_gen/platformio.py +1 -3
  5. esphome/codegen.py +1 -0
  6. esphome/components/animation/animation.cpp +2 -2
  7. esphome/components/api/__init__.py +167 -3
  8. esphome/components/api/api_connection.cpp +84 -41
  9. esphome/components/api/api_connection.h +22 -16
  10. esphome/components/api/api_frame_helper.cpp +33 -19
  11. esphome/components/api/api_frame_helper.h +19 -4
  12. esphome/components/api/api_frame_helper_noise.cpp +41 -53
  13. esphome/components/api/api_frame_helper_noise.h +1 -1
  14. esphome/components/api/api_frame_helper_plaintext.cpp +22 -31
  15. esphome/components/api/api_frame_helper_plaintext.h +1 -1
  16. esphome/components/api/api_pb2.cpp +189 -15
  17. esphome/components/api/api_pb2.h +132 -20
  18. esphome/components/api/api_pb2_dump.cpp +97 -9
  19. esphome/components/api/api_pb2_service.cpp +118 -160
  20. esphome/components/api/api_pb2_service.h +31 -3
  21. esphome/components/api/api_server.cpp +78 -11
  22. esphome/components/api/api_server.h +32 -4
  23. esphome/components/api/custom_api_device.h +8 -8
  24. esphome/components/api/homeassistant_service.h +123 -6
  25. esphome/components/api/proto.h +6 -2
  26. esphome/components/api/user_services.h +2 -2
  27. esphome/components/as7341/sensor.py +1 -1
  28. esphome/components/audio/__init__.py +1 -1
  29. esphome/components/audio/audio.cpp +1 -1
  30. esphome/components/audio/audio_decoder.cpp +9 -9
  31. esphome/components/bl0906/bl0906.cpp +2 -2
  32. esphome/components/bl0942/bl0942.cpp +2 -2
  33. esphome/components/ble_client/__init__.py +1 -1
  34. esphome/components/bluetooth_proxy/__init__.py +4 -30
  35. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +11 -4
  36. esphome/components/bluetooth_proxy/bluetooth_connection.h +2 -2
  37. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +2 -2
  38. esphome/components/camera_encoder/__init__.py +2 -4
  39. esphome/components/camera_encoder/esp32_camera_jpeg_encoder.cpp +4 -2
  40. esphome/components/camera_encoder/esp32_camera_jpeg_encoder.h +3 -1
  41. esphome/components/canbus/canbus.cpp +7 -5
  42. esphome/components/canbus/canbus.h +4 -4
  43. esphome/components/captive_portal/__init__.py +18 -1
  44. esphome/components/captive_portal/captive_portal.cpp +40 -46
  45. esphome/components/captive_portal/captive_portal.h +20 -22
  46. esphome/components/captive_portal/dns_server_esp32_idf.cpp +205 -0
  47. esphome/components/captive_portal/dns_server_esp32_idf.h +27 -0
  48. esphome/components/ccs811/ccs811.cpp +1 -1
  49. esphome/components/climate/climate.cpp +10 -7
  50. esphome/components/cm1106/cm1106.cpp +1 -1
  51. esphome/components/copy/lock/copy_lock.cpp +1 -1
  52. esphome/components/cover/cover.cpp +1 -0
  53. esphome/components/daikin_arc/daikin_arc.cpp +19 -12
  54. esphome/components/deep_sleep/__init__.py +9 -2
  55. esphome/components/deep_sleep/deep_sleep_component.h +11 -9
  56. esphome/components/deep_sleep/deep_sleep_esp32.cpp +51 -27
  57. esphome/components/ektf2232/touchscreen/__init__.py +8 -5
  58. esphome/components/ektf2232/touchscreen/ektf2232.cpp +4 -4
  59. esphome/components/ektf2232/touchscreen/ektf2232.h +2 -2
  60. esphome/components/epaper_spi/__init__.py +1 -0
  61. esphome/components/epaper_spi/display.py +80 -0
  62. esphome/components/epaper_spi/epaper_spi.cpp +227 -0
  63. esphome/components/epaper_spi/epaper_spi.h +93 -0
  64. esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.cpp +42 -0
  65. esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.h +45 -0
  66. esphome/components/epaper_spi/epaper_spi_spectra_e6.cpp +135 -0
  67. esphome/components/epaper_spi/epaper_spi_spectra_e6.h +23 -0
  68. esphome/components/es7210/es7210.cpp +3 -3
  69. esphome/components/esp32/__init__.py +254 -339
  70. esphome/components/esp32/boards.py +81 -0
  71. esphome/components/esp32/preferences.cpp +23 -17
  72. esphome/components/esp32_ble/__init__.py +159 -44
  73. esphome/components/esp32_ble/ble.cpp +47 -3
  74. esphome/components/esp32_ble/ble.h +18 -0
  75. esphome/components/esp32_ble/ble_advertising.cpp +7 -3
  76. esphome/components/esp32_ble/ble_advertising.h +4 -0
  77. esphome/components/esp32_ble/ble_uuid.cpp +16 -42
  78. esphome/components/esp32_ble_beacon/__init__.py +3 -4
  79. esphome/components/esp32_ble_client/ble_client_base.cpp +14 -12
  80. esphome/components/esp32_ble_server/__init__.py +28 -14
  81. esphome/components/esp32_ble_server/ble_characteristic.cpp +67 -57
  82. esphome/components/esp32_ble_server/ble_characteristic.h +27 -16
  83. esphome/components/esp32_ble_server/ble_descriptor.cpp +4 -3
  84. esphome/components/esp32_ble_server/ble_descriptor.h +13 -9
  85. esphome/components/esp32_ble_server/ble_server.cpp +59 -24
  86. esphome/components/esp32_ble_server/ble_server.h +38 -20
  87. esphome/components/esp32_ble_server/ble_server_automations.cpp +49 -33
  88. esphome/components/esp32_ble_server/ble_server_automations.h +39 -24
  89. esphome/components/esp32_ble_tracker/__init__.py +25 -80
  90. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +2 -4
  91. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +0 -3
  92. esphome/components/esp32_camera/__init__.py +1 -3
  93. esphome/components/esp32_can/esp32_can.cpp +22 -4
  94. esphome/components/esp32_can/esp32_can.h +3 -0
  95. esphome/components/esp32_hosted/__init__.py +2 -1
  96. esphome/components/esp32_improv/esp32_improv_component.cpp +102 -44
  97. esphome/components/esp32_improv/esp32_improv_component.h +6 -1
  98. esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
  99. esphome/components/esp8266/__init__.py +3 -3
  100. esphome/components/esphome/ota/__init__.py +21 -2
  101. esphome/components/esphome/ota/ota_esphome.cpp +455 -145
  102. esphome/components/esphome/ota/ota_esphome.h +49 -2
  103. esphome/components/ethernet/__init__.py +39 -22
  104. esphome/components/ethernet/ethernet_component.cpp +28 -5
  105. esphome/components/ethernet/ethernet_component.h +5 -1
  106. esphome/components/external_components/__init__.py +8 -6
  107. esphome/components/fingerprint_grow/fingerprint_grow.cpp +1 -1
  108. esphome/components/fingerprint_grow/fingerprint_grow.h +2 -1
  109. esphome/components/font/__init__.py +5 -5
  110. esphome/components/graph/graph.cpp +1 -1
  111. esphome/components/graphical_display_menu/graphical_display_menu.cpp +3 -2
  112. esphome/components/haier/hon_climate.cpp +2 -2
  113. esphome/components/haier/hon_climate.h +1 -1
  114. esphome/components/hdc1080/hdc1080.cpp +42 -34
  115. esphome/components/hdc1080/hdc1080.h +1 -3
  116. esphome/components/homeassistant/number/homeassistant_number.cpp +2 -2
  117. esphome/components/homeassistant/switch/homeassistant_switch.cpp +2 -2
  118. esphome/components/http_request/__init__.py +3 -3
  119. esphome/components/htu21d/htu21d.cpp +13 -18
  120. esphome/components/htu21d/htu21d.h +1 -1
  121. esphome/components/i2s_audio/__init__.py +1 -2
  122. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +1 -1
  123. esphome/components/ili9xxx/ili9xxx_display.cpp +2 -2
  124. esphome/components/improv_serial/improv_serial_component.cpp +12 -15
  125. esphome/components/improv_serial/improv_serial_component.h +6 -8
  126. esphome/components/json/json_util.cpp +35 -43
  127. esphome/components/json/json_util.h +57 -0
  128. esphome/components/kamstrup_kmp/kamstrup_kmp.cpp +2 -2
  129. esphome/components/key_collector/key_collector.h +4 -4
  130. esphome/components/libretiny/__init__.py +6 -6
  131. esphome/components/libretiny/preferences.cpp +23 -16
  132. esphome/components/light/light_call.cpp +98 -120
  133. esphome/components/light/light_call.h +17 -7
  134. esphome/components/lm75b/__init__.py +0 -0
  135. esphome/components/lm75b/lm75b.cpp +39 -0
  136. esphome/components/lm75b/lm75b.h +19 -0
  137. esphome/components/lm75b/sensor.py +34 -0
  138. esphome/components/lock/lock.h +12 -6
  139. esphome/components/logger/__init__.py +15 -27
  140. esphome/components/logger/logger.cpp +10 -20
  141. esphome/components/logger/logger.h +105 -62
  142. esphome/components/logger/logger_esp32.cpp +0 -48
  143. esphome/components/logger/logger_zephyr.cpp +2 -3
  144. esphome/components/logger/select/logger_level_select.cpp +6 -7
  145. esphome/components/logger/select/logger_level_select.h +7 -0
  146. esphome/components/ltr501/ltr501.cpp +7 -6
  147. esphome/components/ltr_als_ps/ltr_als_ps.cpp +7 -6
  148. esphome/components/matrix_keypad/matrix_keypad.h +4 -4
  149. esphome/components/max7219digit/max7219digit.cpp +1 -1
  150. esphome/components/mcp2515/mcp2515.cpp +31 -3
  151. esphome/components/mcp2515/mcp2515_defs.h +3 -1
  152. esphome/components/md5/md5.cpp +0 -26
  153. esphome/components/md5/md5.h +10 -20
  154. esphome/components/mdns/__init__.py +19 -6
  155. esphome/components/mdns/mdns_component.cpp +27 -59
  156. esphome/components/mdns/mdns_component.h +23 -10
  157. esphome/components/mdns/mdns_esp32.cpp +7 -7
  158. esphome/components/mdns/mdns_esp8266.cpp +6 -6
  159. esphome/components/mdns/mdns_libretiny.cpp +3 -3
  160. esphome/components/mdns/mdns_rp2040.cpp +3 -3
  161. esphome/components/mipi/__init__.py +1 -5
  162. esphome/components/mipi_spi/display.py +24 -8
  163. esphome/components/mipi_spi/mipi_spi.h +3 -3
  164. esphome/components/mixer/speaker/mixer_speaker.cpp +3 -3
  165. esphome/components/mmc5603/mmc5603.cpp +3 -3
  166. esphome/components/modbus/modbus.cpp +27 -13
  167. esphome/components/modbus/modbus.h +5 -3
  168. esphome/components/modbus/modbus_definitions.h +86 -0
  169. esphome/components/modbus_controller/__init__.py +29 -1
  170. esphome/components/modbus_controller/const.py +4 -0
  171. esphome/components/modbus_controller/modbus_controller.cpp +38 -13
  172. esphome/components/modbus_controller/modbus_controller.h +18 -29
  173. esphome/components/mpr121/mpr121.cpp +41 -42
  174. esphome/components/mpr121/mpr121.h +0 -1
  175. esphome/components/nau7802/nau7802.cpp +2 -2
  176. esphome/components/network/__init__.py +7 -3
  177. esphome/components/nextion/display.py +4 -4
  178. esphome/components/nextion/nextion.cpp +8 -8
  179. esphome/components/number/__init__.py +2 -0
  180. esphome/components/number/number_call.cpp +23 -12
  181. esphome/components/number/number_call.h +5 -0
  182. esphome/components/online_image/bmp_image.cpp +2 -1
  183. esphome/components/online_image/jpeg_image.cpp +4 -2
  184. esphome/components/openthread/openthread.cpp +6 -7
  185. esphome/components/openthread/openthread.h +0 -1
  186. esphome/components/ota/ota_backend.h +1 -0
  187. esphome/components/packages/__init__.py +10 -8
  188. esphome/components/packet_transport/packet_transport.cpp +2 -0
  189. esphome/components/pid/pid_controller.cpp +1 -1
  190. esphome/components/prometheus/prometheus_handler.cpp +239 -239
  191. esphome/components/psram/__init__.py +30 -28
  192. esphome/components/qmc5883l/qmc5883l.cpp +15 -0
  193. esphome/components/qmc5883l/qmc5883l.h +3 -0
  194. esphome/components/qmc5883l/sensor.py +31 -12
  195. esphome/components/remote_base/gobox_protocol.cpp +3 -3
  196. esphome/components/remote_receiver/__init__.py +14 -2
  197. esphome/components/remote_receiver/{remote_receiver_esp8266.cpp → remote_receiver.cpp} +2 -2
  198. esphome/components/remote_receiver/remote_receiver.h +4 -0
  199. esphome/components/remote_receiver/remote_receiver_esp32.cpp +18 -1
  200. esphome/components/remote_transmitter/__init__.py +2 -2
  201. esphome/components/remote_transmitter/remote_transmitter.cpp +103 -0
  202. esphome/components/rp2040/__init__.py +11 -11
  203. esphome/components/rtttl/rtttl.cpp +2 -2
  204. esphome/components/scd30/sensor.py +1 -1
  205. esphome/components/script/__init__.py +1 -1
  206. esphome/components/script/script.h +7 -7
  207. esphome/components/select/select.cpp +5 -4
  208. esphome/components/select/select_call.cpp +1 -1
  209. esphome/components/sensirion_common/i2c_sensirion.cpp +2 -1
  210. esphome/components/sensor/__init__.py +2 -0
  211. esphome/components/sha256/__init__.py +22 -0
  212. esphome/components/sha256/sha256.cpp +116 -0
  213. esphome/components/sha256/sha256.h +60 -0
  214. esphome/components/sim800l/sim800l.cpp +8 -4
  215. esphome/components/socket/lwip_raw_tcp_impl.cpp +34 -6
  216. esphome/components/sonoff_d1/sonoff_d1.cpp +1 -1
  217. esphome/components/spi/__init__.py +0 -3
  218. esphome/components/split_buffer/__init__.py +5 -0
  219. esphome/components/split_buffer/split_buffer.cpp +133 -0
  220. esphome/components/split_buffer/split_buffer.h +40 -0
  221. esphome/components/sps30/sps30.cpp +14 -10
  222. esphome/components/sps30/sps30.h +2 -0
  223. esphome/components/st7567_i2c/st7567_i2c.cpp +3 -1
  224. esphome/components/st7789v/st7789v.cpp +3 -2
  225. esphome/components/statsd/statsd.cpp +1 -1
  226. esphome/components/substitutions/__init__.py +3 -1
  227. esphome/components/substitutions/jinja.py +13 -3
  228. esphome/components/sx126x/__init__.py +16 -0
  229. esphome/components/sx126x/sx126x.cpp +15 -1
  230. esphome/components/sx126x/sx126x.h +9 -1
  231. esphome/components/sx126x/sx126x_reg.h +2 -0
  232. esphome/components/text_sensor/text_sensor.cpp +16 -0
  233. esphome/components/text_sensor/text_sensor.h +3 -10
  234. esphome/components/tormatic/tormatic_cover.cpp +1 -1
  235. esphome/components/tuya/select/tuya_select.cpp +1 -1
  236. esphome/components/tuya/tuya.cpp +29 -4
  237. esphome/components/uart/__init__.py +36 -26
  238. esphome/components/uart/uart.h +6 -0
  239. esphome/components/uart/uart_component.cpp +8 -0
  240. esphome/components/uart/uart_component.h +28 -0
  241. esphome/components/uart/uart_component_esp_idf.cpp +64 -10
  242. esphome/components/uart/uart_component_esp_idf.h +5 -2
  243. esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +1 -1
  244. esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.cpp +1 -1
  245. esphome/components/uponor_smatrix/uponor_smatrix.cpp +3 -3
  246. esphome/components/usb_host/__init__.py +2 -1
  247. esphome/components/usb_host/usb_host.h +82 -13
  248. esphome/components/usb_host/usb_host_client.cpp +180 -24
  249. esphome/components/usb_host/usb_host_component.cpp +1 -1
  250. esphome/components/usb_uart/__init__.py +0 -1
  251. esphome/components/usb_uart/ch34x.cpp +4 -4
  252. esphome/components/usb_uart/cp210x.cpp +3 -3
  253. esphome/components/usb_uart/usb_uart.cpp +88 -32
  254. esphome/components/usb_uart/usb_uart.h +30 -6
  255. esphome/components/valve/valve.cpp +1 -0
  256. esphome/components/veml7700/veml7700.cpp +7 -6
  257. esphome/components/version/version_text_sensor.cpp +2 -1
  258. esphome/components/voice_assistant/voice_assistant.cpp +3 -3
  259. esphome/components/waveshare_epaper/waveshare_epaper.cpp +4 -4
  260. esphome/components/web_server/list_entities.cpp +3 -4
  261. esphome/components/web_server/list_entities.h +8 -10
  262. esphome/components/web_server/ota/__init__.py +1 -1
  263. esphome/components/web_server/ota/ota_web_server.cpp +9 -3
  264. esphome/components/web_server/web_server.cpp +509 -404
  265. esphome/components/web_server/web_server.h +5 -6
  266. esphome/components/web_server/web_server_v1.cpp +21 -19
  267. esphome/components/web_server_base/__init__.py +5 -2
  268. esphome/components/web_server_base/web_server_base.h +27 -7
  269. esphome/components/web_server_idf/__init__.py +1 -1
  270. esphome/components/web_server_idf/multipart.cpp +2 -2
  271. esphome/components/web_server_idf/multipart.h +2 -2
  272. esphome/components/web_server_idf/utils.cpp +2 -2
  273. esphome/components/web_server_idf/utils.h +2 -2
  274. esphome/components/web_server_idf/web_server_idf.cpp +118 -26
  275. esphome/components/web_server_idf/web_server_idf.h +12 -10
  276. esphome/components/wifi/__init__.py +13 -11
  277. esphome/components/wifi/wifi_component.cpp +73 -56
  278. esphome/components/wifi/wifi_component.h +4 -4
  279. esphome/components/wifi/wifi_component_esp8266.cpp +1 -1
  280. esphome/components/wifi/wifi_component_esp_idf.cpp +24 -4
  281. esphome/components/wireguard/__init__.py +1 -1
  282. esphome/components/wts01/__init__.py +0 -0
  283. esphome/components/wts01/sensor.py +41 -0
  284. esphome/components/wts01/wts01.cpp +91 -0
  285. esphome/components/wts01/wts01.h +27 -0
  286. esphome/components/zephyr/__init__.py +5 -5
  287. esphome/components/zwave_proxy/__init__.py +43 -0
  288. esphome/components/zwave_proxy/zwave_proxy.cpp +346 -0
  289. esphome/components/zwave_proxy/zwave_proxy.h +93 -0
  290. esphome/config.py +79 -24
  291. esphome/config_validation.py +13 -15
  292. esphome/const.py +9 -2
  293. esphome/core/__init__.py +31 -22
  294. esphome/core/component.cpp +28 -18
  295. esphome/core/component_iterator.h +2 -1
  296. esphome/core/config.py +15 -15
  297. esphome/core/defines.h +19 -0
  298. esphome/core/hash_base.h +56 -0
  299. esphome/core/helpers.cpp +19 -3
  300. esphome/core/helpers.h +26 -0
  301. esphome/core/scheduler.cpp +5 -21
  302. esphome/core/scheduler.h +19 -8
  303. esphome/core/string_ref.h +1 -1
  304. esphome/core/time.cpp +5 -5
  305. esphome/cpp_generator.py +4 -29
  306. esphome/dashboard/const.py +21 -4
  307. esphome/dashboard/core.py +10 -8
  308. esphome/dashboard/dns.py +15 -0
  309. esphome/dashboard/entries.py +15 -21
  310. esphome/dashboard/models.py +76 -0
  311. esphome/dashboard/settings.py +7 -7
  312. esphome/dashboard/status/mdns.py +46 -2
  313. esphome/dashboard/web_server.py +367 -93
  314. esphome/espota2.py +111 -31
  315. esphome/external_files.py +6 -7
  316. esphome/git.py +8 -0
  317. esphome/helpers.py +124 -77
  318. esphome/loader.py +8 -9
  319. esphome/platformio_api.py +25 -18
  320. esphome/storage_json.py +26 -21
  321. esphome/types.py +30 -2
  322. esphome/util.py +32 -16
  323. esphome/vscode.py +8 -8
  324. esphome/wizard.py +10 -10
  325. esphome/writer.py +50 -15
  326. esphome/yaml_util.py +37 -31
  327. esphome/zeroconf.py +12 -3
  328. {esphome-2025.9.2.dist-info → esphome-2025.10.0b1.dist-info}/METADATA +11 -11
  329. {esphome-2025.9.2.dist-info → esphome-2025.10.0b1.dist-info}/RECORD +333 -313
  330. esphome/components/event_emitter/__init__.py +0 -5
  331. esphome/components/event_emitter/event_emitter.cpp +0 -14
  332. esphome/components/event_emitter/event_emitter.h +0 -63
  333. esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -125
  334. esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +0 -107
  335. esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +0 -110
  336. esphome/components/uart/uart_component_esp32_arduino.cpp +0 -214
  337. esphome/components/uart/uart_component_esp32_arduino.h +0 -60
  338. esphome/components/wifi/wifi_component_esp32_arduino.cpp +0 -860
  339. esphome/core/string_ref.cpp +0 -12
  340. esphome/dashboard/util/file.py +0 -63
  341. {esphome-2025.9.2.dist-info → esphome-2025.10.0b1.dist-info}/WHEEL +0 -0
  342. {esphome-2025.9.2.dist-info → esphome-2025.10.0b1.dist-info}/entry_points.txt +0 -0
  343. {esphome-2025.9.2.dist-info → esphome-2025.10.0b1.dist-info}/licenses/LICENSE +0 -0
  344. {esphome-2025.9.2.dist-info → esphome-2025.10.0b1.dist-info}/top_level.txt +0 -0
@@ -10,11 +10,15 @@ namespace light {
10
10
  static const char *const TAG = "light";
11
11
 
12
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 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);
13
+ static void clamp_and_log_if_invalid(const char *name, float &value, const LogString *param_name, float min = 0.0f,
14
+ float max = 1.0f) {
15
+ if (value < min || value > max) {
16
+ ESP_LOGW(TAG, "'%s': %s value %.2f is out of range [%.1f - %.1f]", name, LOG_STR_ARG(param_name), value, min, max);
17
+ value = clamp(value, min, max);
18
+ }
16
19
  }
17
20
 
21
+ #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_WARN
18
22
  static void log_feature_not_supported(const char *name, const LogString *feature) {
19
23
  ESP_LOGW(TAG, "'%s': %s not supported", name, LOG_STR_ARG(feature));
20
24
  }
@@ -27,7 +31,6 @@ static void log_invalid_parameter(const char *name, const LogString *message) {
27
31
  ESP_LOGW(TAG, "'%s': %s", name, LOG_STR_ARG(message));
28
32
  }
29
33
  #else
30
- #define log_validation_warning(name, param_name, val, min, max)
31
34
  #define log_feature_not_supported(name, feature)
32
35
  #define log_color_mode_not_supported(name, feature)
33
36
  #define log_invalid_parameter(name, message)
@@ -44,7 +47,7 @@ static void log_invalid_parameter(const char *name, const LogString *message) {
44
47
  } \
45
48
  LightCall &LightCall::set_##name(type name) { \
46
49
  this->name##_ = name; \
47
- this->set_flag_(flag, true); \
50
+ this->set_flag_(flag); \
48
51
  return *this; \
49
52
  }
50
53
 
@@ -181,6 +184,16 @@ void LightCall::perform() {
181
184
  }
182
185
  }
183
186
 
187
+ void LightCall::log_and_clear_unsupported_(FieldFlags flag, const LogString *feature, bool use_color_mode_log) {
188
+ auto *name = this->parent_->get_name().c_str();
189
+ if (use_color_mode_log) {
190
+ log_color_mode_not_supported(name, feature);
191
+ } else {
192
+ log_feature_not_supported(name, feature);
193
+ }
194
+ this->clear_flag_(flag);
195
+ }
196
+
184
197
  LightColorValues LightCall::validate_() {
185
198
  auto *name = this->parent_->get_name().c_str();
186
199
  auto traits = this->parent_->get_traits();
@@ -188,141 +201,108 @@ LightColorValues LightCall::validate_() {
188
201
  // Color mode check
189
202
  if (this->has_color_mode() && !traits.supports_color_mode(this->color_mode_)) {
190
203
  ESP_LOGW(TAG, "'%s' does not support color mode %s", name, LOG_STR_ARG(color_mode_to_human(this->color_mode_)));
191
- this->set_flag_(FLAG_HAS_COLOR_MODE, false);
204
+ this->clear_flag_(FLAG_HAS_COLOR_MODE);
192
205
  }
193
206
 
194
207
  // Ensure there is always a color mode set
195
208
  if (!this->has_color_mode()) {
196
209
  this->color_mode_ = this->compute_color_mode_();
197
- this->set_flag_(FLAG_HAS_COLOR_MODE, true);
210
+ this->set_flag_(FLAG_HAS_COLOR_MODE);
198
211
  }
199
212
  auto color_mode = this->color_mode_;
200
213
 
201
214
  // Transform calls that use non-native parameters for the current mode.
202
215
  this->transform_parameters_();
203
216
 
204
- // Brightness exists check
205
- if (this->has_brightness() && this->brightness_ > 0.0f && !(color_mode & ColorCapability::BRIGHTNESS)) {
206
- log_feature_not_supported(name, LOG_STR("brightness"));
207
- this->set_flag_(FLAG_HAS_BRIGHTNESS, false);
208
- }
217
+ // Business logic adjustments before validation
218
+ // Flag whether an explicit turn off was requested, in which case we'll also stop the effect.
219
+ bool explicit_turn_off_request = this->has_state() && !this->state_;
209
220
 
210
- // Transition length possible check
211
- if (this->has_transition_() && this->transition_length_ != 0 && !(color_mode & ColorCapability::BRIGHTNESS)) {
212
- log_feature_not_supported(name, LOG_STR("transitions"));
213
- this->set_flag_(FLAG_HAS_TRANSITION, false);
221
+ // Turn off when brightness is set to zero, and reset brightness (so that it has nonzero brightness when turned on).
222
+ if (this->has_brightness() && this->brightness_ == 0.0f) {
223
+ this->state_ = false;
224
+ this->set_flag_(FLAG_HAS_STATE);
225
+ this->brightness_ = 1.0f;
214
226
  }
215
227
 
216
- // Color brightness exists check
217
- if (this->has_color_brightness() && this->color_brightness_ > 0.0f && !(color_mode & ColorCapability::RGB)) {
218
- log_color_mode_not_supported(name, LOG_STR("RGB brightness"));
219
- this->set_flag_(FLAG_HAS_COLOR_BRIGHTNESS, false);
228
+ // Set color brightness to 100% if currently zero and a color is set.
229
+ if ((this->has_red() || this->has_green() || this->has_blue()) && !this->has_color_brightness() &&
230
+ this->parent_->remote_values.get_color_brightness() == 0.0f) {
231
+ this->color_brightness_ = 1.0f;
232
+ this->set_flag_(FLAG_HAS_COLOR_BRIGHTNESS);
220
233
  }
221
234
 
235
+ // Capability validation
236
+ if (this->has_brightness() && this->brightness_ > 0.0f && !(color_mode & ColorCapability::BRIGHTNESS))
237
+ this->log_and_clear_unsupported_(FLAG_HAS_BRIGHTNESS, LOG_STR("brightness"), false);
238
+
239
+ // Transition length possible check
240
+ if (this->has_transition_() && this->transition_length_ != 0 && !(color_mode & ColorCapability::BRIGHTNESS))
241
+ this->log_and_clear_unsupported_(FLAG_HAS_TRANSITION, LOG_STR("transitions"), false);
242
+
243
+ if (this->has_color_brightness() && this->color_brightness_ > 0.0f && !(color_mode & ColorCapability::RGB))
244
+ this->log_and_clear_unsupported_(FLAG_HAS_COLOR_BRIGHTNESS, LOG_STR("RGB brightness"), true);
245
+
222
246
  // RGB exists check
223
- if ((this->has_red() && this->red_ > 0.0f) || (this->has_green() && this->green_ > 0.0f) ||
224
- (this->has_blue() && this->blue_ > 0.0f)) {
225
- if (!(color_mode & ColorCapability::RGB)) {
226
- log_color_mode_not_supported(name, LOG_STR("RGB color"));
227
- this->set_flag_(FLAG_HAS_RED, false);
228
- this->set_flag_(FLAG_HAS_GREEN, false);
229
- this->set_flag_(FLAG_HAS_BLUE, false);
230
- }
247
+ if (((this->has_red() && this->red_ > 0.0f) || (this->has_green() && this->green_ > 0.0f) ||
248
+ (this->has_blue() && this->blue_ > 0.0f)) &&
249
+ !(color_mode & ColorCapability::RGB)) {
250
+ log_color_mode_not_supported(name, LOG_STR("RGB color"));
251
+ this->clear_flag_(FLAG_HAS_RED);
252
+ this->clear_flag_(FLAG_HAS_GREEN);
253
+ this->clear_flag_(FLAG_HAS_BLUE);
231
254
  }
232
255
 
233
256
  // White value exists check
234
257
  if (this->has_white() && this->white_ > 0.0f &&
235
- !(color_mode & ColorCapability::WHITE || color_mode & ColorCapability::COLD_WARM_WHITE)) {
236
- log_color_mode_not_supported(name, LOG_STR("white value"));
237
- this->set_flag_(FLAG_HAS_WHITE, false);
238
- }
258
+ !(color_mode & ColorCapability::WHITE || color_mode & ColorCapability::COLD_WARM_WHITE))
259
+ this->log_and_clear_unsupported_(FLAG_HAS_WHITE, LOG_STR("white value"), true);
239
260
 
240
261
  // Color temperature exists check
241
262
  if (this->has_color_temperature() &&
242
- !(color_mode & ColorCapability::COLOR_TEMPERATURE || color_mode & ColorCapability::COLD_WARM_WHITE)) {
243
- log_color_mode_not_supported(name, LOG_STR("color temperature"));
244
- this->set_flag_(FLAG_HAS_COLOR_TEMPERATURE, false);
245
- }
263
+ !(color_mode & ColorCapability::COLOR_TEMPERATURE || color_mode & ColorCapability::COLD_WARM_WHITE))
264
+ this->log_and_clear_unsupported_(FLAG_HAS_COLOR_TEMPERATURE, LOG_STR("color temperature"), true);
246
265
 
247
266
  // Cold/warm white value exists check
248
- if ((this->has_cold_white() && this->cold_white_ > 0.0f) || (this->has_warm_white() && this->warm_white_ > 0.0f)) {
249
- if (!(color_mode & ColorCapability::COLD_WARM_WHITE)) {
250
- log_color_mode_not_supported(name, LOG_STR("cold/warm white value"));
251
- this->set_flag_(FLAG_HAS_COLD_WHITE, false);
252
- this->set_flag_(FLAG_HAS_WARM_WHITE, false);
253
- }
254
- }
255
-
256
- #define VALIDATE_RANGE_(name_, upper_name, min, max) \
257
- if (this->has_##name_()) { \
258
- auto val = this->name_##_; \
259
- if (val < (min) || val > (max)) { \
260
- log_validation_warning(name, LOG_STR(upper_name), val, (min), (max)); \
261
- this->name_##_ = clamp(val, (min), (max)); \
262
- } \
267
+ if (((this->has_cold_white() && this->cold_white_ > 0.0f) || (this->has_warm_white() && this->warm_white_ > 0.0f)) &&
268
+ !(color_mode & ColorCapability::COLD_WARM_WHITE)) {
269
+ log_color_mode_not_supported(name, LOG_STR("cold/warm white value"));
270
+ this->clear_flag_(FLAG_HAS_COLD_WHITE);
271
+ this->clear_flag_(FLAG_HAS_WARM_WHITE);
263
272
  }
264
- #define VALIDATE_RANGE(name, upper_name) VALIDATE_RANGE_(name, upper_name, 0.0f, 1.0f)
265
-
266
- // Range checks
267
- VALIDATE_RANGE(brightness, "Brightness")
268
- VALIDATE_RANGE(color_brightness, "Color brightness")
269
- VALIDATE_RANGE(red, "Red")
270
- VALIDATE_RANGE(green, "Green")
271
- VALIDATE_RANGE(blue, "Blue")
272
- VALIDATE_RANGE(white, "White")
273
- VALIDATE_RANGE(cold_white, "Cold white")
274
- VALIDATE_RANGE(warm_white, "Warm white")
275
- VALIDATE_RANGE_(color_temperature, "Color temperature", traits.get_min_mireds(), traits.get_max_mireds())
276
-
277
- // Flag whether an explicit turn off was requested, in which case we'll also stop the effect.
278
- bool explicit_turn_off_request = this->has_state() && !this->state_;
279
273
 
280
- // Turn off when brightness is set to zero, and reset brightness (so that it has nonzero brightness when turned on).
281
- if (this->has_brightness() && this->brightness_ == 0.0f) {
282
- this->state_ = false;
283
- this->set_flag_(FLAG_HAS_STATE, true);
284
- this->brightness_ = 1.0f;
285
- }
286
-
287
- // Set color brightness to 100% if currently zero and a color is set.
288
- if (this->has_red() || this->has_green() || this->has_blue()) {
289
- if (!this->has_color_brightness() && this->parent_->remote_values.get_color_brightness() == 0.0f) {
290
- this->color_brightness_ = 1.0f;
291
- this->set_flag_(FLAG_HAS_COLOR_BRIGHTNESS, true);
292
- }
293
- }
294
-
295
- // Create color values for the light with this call applied.
274
+ // Create color values and validate+apply ranges in one step to eliminate duplicate checks
296
275
  auto v = this->parent_->remote_values;
297
276
  if (this->has_color_mode())
298
277
  v.set_color_mode(this->color_mode_);
299
278
  if (this->has_state())
300
279
  v.set_state(this->state_);
301
- if (this->has_brightness())
302
- v.set_brightness(this->brightness_);
303
- if (this->has_color_brightness())
304
- v.set_color_brightness(this->color_brightness_);
305
- if (this->has_red())
306
- v.set_red(this->red_);
307
- if (this->has_green())
308
- v.set_green(this->green_);
309
- if (this->has_blue())
310
- v.set_blue(this->blue_);
311
- if (this->has_white())
312
- v.set_white(this->white_);
313
- if (this->has_color_temperature())
314
- v.set_color_temperature(this->color_temperature_);
315
- if (this->has_cold_white())
316
- v.set_cold_white(this->cold_white_);
317
- if (this->has_warm_white())
318
- v.set_warm_white(this->warm_white_);
280
+
281
+ #define VALIDATE_AND_APPLY(field, setter, name_str, ...) \
282
+ if (this->has_##field()) { \
283
+ clamp_and_log_if_invalid(name, this->field##_, LOG_STR(name_str), ##__VA_ARGS__); \
284
+ v.setter(this->field##_); \
285
+ }
286
+
287
+ VALIDATE_AND_APPLY(brightness, set_brightness, "Brightness")
288
+ VALIDATE_AND_APPLY(color_brightness, set_color_brightness, "Color brightness")
289
+ VALIDATE_AND_APPLY(red, set_red, "Red")
290
+ VALIDATE_AND_APPLY(green, set_green, "Green")
291
+ VALIDATE_AND_APPLY(blue, set_blue, "Blue")
292
+ VALIDATE_AND_APPLY(white, set_white, "White")
293
+ VALIDATE_AND_APPLY(cold_white, set_cold_white, "Cold white")
294
+ VALIDATE_AND_APPLY(warm_white, set_warm_white, "Warm white")
295
+ VALIDATE_AND_APPLY(color_temperature, set_color_temperature, "Color temperature", traits.get_min_mireds(),
296
+ traits.get_max_mireds())
297
+
298
+ #undef VALIDATE_AND_APPLY
319
299
 
320
300
  v.normalize_color();
321
301
 
322
302
  // Flash length check
323
303
  if (this->has_flash_() && this->flash_length_ == 0) {
324
- log_invalid_parameter(name, LOG_STR("flash length must be greater than zero"));
325
- this->set_flag_(FLAG_HAS_FLASH, false);
304
+ log_invalid_parameter(name, LOG_STR("flash length must be >0"));
305
+ this->clear_flag_(FLAG_HAS_FLASH);
326
306
  }
327
307
 
328
308
  // validate transition length/flash length/effect not used at the same time
@@ -330,42 +310,40 @@ LightColorValues LightCall::validate_() {
330
310
 
331
311
  // If effect is already active, remove effect start
332
312
  if (this->has_effect_() && this->effect_ == this->parent_->active_effect_index_) {
333
- this->set_flag_(FLAG_HAS_EFFECT, false);
313
+ this->clear_flag_(FLAG_HAS_EFFECT);
334
314
  }
335
315
 
336
316
  // validate effect index
337
317
  if (this->has_effect_() && this->effect_ > this->parent_->effects_.size()) {
338
318
  ESP_LOGW(TAG, "'%s': invalid effect index %" PRIu32, name, this->effect_);
339
- this->set_flag_(FLAG_HAS_EFFECT, false);
319
+ this->clear_flag_(FLAG_HAS_EFFECT);
340
320
  }
341
321
 
342
322
  if (this->has_effect_() && (this->has_transition_() || this->has_flash_())) {
343
323
  log_invalid_parameter(name, LOG_STR("effect cannot be used with transition/flash"));
344
- this->set_flag_(FLAG_HAS_TRANSITION, false);
345
- this->set_flag_(FLAG_HAS_FLASH, false);
324
+ this->clear_flag_(FLAG_HAS_TRANSITION);
325
+ this->clear_flag_(FLAG_HAS_FLASH);
346
326
  }
347
327
 
348
328
  if (this->has_flash_() && this->has_transition_()) {
349
329
  log_invalid_parameter(name, LOG_STR("flash cannot be used with transition"));
350
- this->set_flag_(FLAG_HAS_TRANSITION, false);
330
+ this->clear_flag_(FLAG_HAS_TRANSITION);
351
331
  }
352
332
 
353
333
  if (!this->has_transition_() && !this->has_flash_() && (!this->has_effect_() || this->effect_ == 0) &&
354
334
  supports_transition) {
355
335
  // nothing specified and light supports transitions, set default transition length
356
336
  this->transition_length_ = this->parent_->default_transition_length_;
357
- this->set_flag_(FLAG_HAS_TRANSITION, true);
337
+ this->set_flag_(FLAG_HAS_TRANSITION);
358
338
  }
359
339
 
360
340
  if (this->has_transition_() && this->transition_length_ == 0) {
361
341
  // 0 transition is interpreted as no transition (instant change)
362
- this->set_flag_(FLAG_HAS_TRANSITION, false);
342
+ this->clear_flag_(FLAG_HAS_TRANSITION);
363
343
  }
364
344
 
365
- if (this->has_transition_() && !supports_transition) {
366
- log_feature_not_supported(name, LOG_STR("transitions"));
367
- this->set_flag_(FLAG_HAS_TRANSITION, false);
368
- }
345
+ if (this->has_transition_() && !supports_transition)
346
+ this->log_and_clear_unsupported_(FLAG_HAS_TRANSITION, LOG_STR("transitions"), false);
369
347
 
370
348
  // If not a flash and turning the light off, then disable the light
371
349
  // Do not use light color values directly, so that effects can set 0% brightness
@@ -374,17 +352,17 @@ LightColorValues LightCall::validate_() {
374
352
  if (!this->has_flash_() && !target_state) {
375
353
  if (this->has_effect_()) {
376
354
  log_invalid_parameter(name, LOG_STR("cannot start effect when turning off"));
377
- this->set_flag_(FLAG_HAS_EFFECT, false);
355
+ this->clear_flag_(FLAG_HAS_EFFECT);
378
356
  } else if (this->parent_->active_effect_index_ != 0 && explicit_turn_off_request) {
379
357
  // Auto turn off effect
380
358
  this->effect_ = 0;
381
- this->set_flag_(FLAG_HAS_EFFECT, true);
359
+ this->set_flag_(FLAG_HAS_EFFECT);
382
360
  }
383
361
  }
384
362
 
385
363
  // Disable saving for flashes
386
364
  if (this->has_flash_())
387
- this->set_flag_(FLAG_SAVE, false);
365
+ this->clear_flag_(FLAG_SAVE);
388
366
 
389
367
  return v;
390
368
  }
@@ -418,12 +396,12 @@ void LightCall::transform_parameters_() {
418
396
  const float gamma = this->parent_->get_gamma_correct();
419
397
  this->cold_white_ = gamma_uncorrect(cw_fraction / max_cw_ww, gamma);
420
398
  this->warm_white_ = gamma_uncorrect(ww_fraction / max_cw_ww, gamma);
421
- this->set_flag_(FLAG_HAS_COLD_WHITE, true);
422
- this->set_flag_(FLAG_HAS_WARM_WHITE, true);
399
+ this->set_flag_(FLAG_HAS_COLD_WHITE);
400
+ this->set_flag_(FLAG_HAS_WARM_WHITE);
423
401
  }
424
402
  if (this->has_white()) {
425
403
  this->brightness_ = this->white_;
426
- this->set_flag_(FLAG_HAS_BRIGHTNESS, true);
404
+ this->set_flag_(FLAG_HAS_BRIGHTNESS);
427
405
  }
428
406
  }
429
407
  }
@@ -630,7 +608,7 @@ LightCall &LightCall::set_effect(optional<std::string> effect) {
630
608
  }
631
609
  LightCall &LightCall::set_effect(uint32_t effect_number) {
632
610
  this->effect_ = effect_number;
633
- this->set_flag_(FLAG_HAS_EFFECT, true);
611
+ this->set_flag_(FLAG_HAS_EFFECT);
634
612
  return *this;
635
613
  }
636
614
  LightCall &LightCall::set_effect(optional<uint32_t> effect_number) {
@@ -4,6 +4,10 @@
4
4
  #include <set>
5
5
 
6
6
  namespace esphome {
7
+
8
+ // Forward declaration
9
+ struct LogString;
10
+
7
11
  namespace light {
8
12
 
9
13
  class LightState;
@@ -207,14 +211,14 @@ class LightCall {
207
211
  FLAG_SAVE = 1 << 15,
208
212
  };
209
213
 
210
- bool has_transition_() { return (this->flags_ & FLAG_HAS_TRANSITION) != 0; }
211
- bool has_flash_() { return (this->flags_ & FLAG_HAS_FLASH) != 0; }
212
- bool has_effect_() { return (this->flags_ & FLAG_HAS_EFFECT) != 0; }
213
- bool get_publish_() { return (this->flags_ & FLAG_PUBLISH) != 0; }
214
- bool get_save_() { return (this->flags_ & FLAG_SAVE) != 0; }
214
+ inline bool has_transition_() { return (this->flags_ & FLAG_HAS_TRANSITION) != 0; }
215
+ inline bool has_flash_() { return (this->flags_ & FLAG_HAS_FLASH) != 0; }
216
+ inline bool has_effect_() { return (this->flags_ & FLAG_HAS_EFFECT) != 0; }
217
+ inline bool get_publish_() { return (this->flags_ & FLAG_PUBLISH) != 0; }
218
+ inline bool get_save_() { return (this->flags_ & FLAG_SAVE) != 0; }
215
219
 
216
- // Helper to set flag
217
- void set_flag_(FieldFlags flag, bool value) {
220
+ // Helper to set flag - defaults to true for common case
221
+ void set_flag_(FieldFlags flag, bool value = true) {
218
222
  if (value) {
219
223
  this->flags_ |= flag;
220
224
  } else {
@@ -222,6 +226,12 @@ class LightCall {
222
226
  }
223
227
  }
224
228
 
229
+ // Helper to clear flag - reduces code size for common case
230
+ void clear_flag_(FieldFlags flag) { this->flags_ &= ~flag; }
231
+
232
+ // Helper to log unsupported feature and clear flag - reduces code duplication
233
+ void log_and_clear_unsupported_(FieldFlags flag, const LogString *feature, bool use_color_mode_log);
234
+
225
235
  LightState *parent_;
226
236
 
227
237
  // Light state values - use flags_ to check if a value has been set.
File without changes
@@ -0,0 +1,39 @@
1
+ #include "lm75b.h"
2
+ #include "esphome/core/log.h"
3
+ #include "esphome/core/hal.h"
4
+
5
+ namespace esphome {
6
+ namespace lm75b {
7
+
8
+ static const char *const TAG = "lm75b";
9
+
10
+ void LM75BComponent::dump_config() {
11
+ ESP_LOGCONFIG(TAG, "LM75B:");
12
+ LOG_I2C_DEVICE(this);
13
+ if (this->is_failed()) {
14
+ ESP_LOGE(TAG, "Setting up LM75B failed!");
15
+ }
16
+ LOG_UPDATE_INTERVAL(this);
17
+ LOG_SENSOR(" ", "Temperature", this);
18
+ }
19
+
20
+ void LM75BComponent::update() {
21
+ // Create a temporary buffer
22
+ uint8_t buff[2];
23
+ if (this->read_register(LM75B_REG_TEMPERATURE, buff, 2) != i2c::ERROR_OK) {
24
+ this->status_set_warning();
25
+ return;
26
+ }
27
+ // Obtain combined 16-bit value
28
+ int16_t raw_temperature = (buff[0] << 8) | buff[1];
29
+ // Read the 11-bit raw temperature value
30
+ raw_temperature >>= 5;
31
+ // Publish the temperature in °C
32
+ this->publish_state(raw_temperature * 0.125);
33
+ if (this->status_has_warning()) {
34
+ this->status_clear_warning();
35
+ }
36
+ }
37
+
38
+ } // namespace lm75b
39
+ } // namespace esphome
@@ -0,0 +1,19 @@
1
+ #pragma once
2
+
3
+ #include "esphome/core/component.h"
4
+ #include "esphome/components/sensor/sensor.h"
5
+ #include "esphome/components/i2c/i2c.h"
6
+
7
+ namespace esphome {
8
+ namespace lm75b {
9
+
10
+ static const uint8_t LM75B_REG_TEMPERATURE = 0x00;
11
+
12
+ class LM75BComponent : public PollingComponent, public i2c::I2CDevice, public sensor::Sensor {
13
+ public:
14
+ void dump_config() override;
15
+ void update() override;
16
+ };
17
+
18
+ } // namespace lm75b
19
+ } // namespace esphome
@@ -0,0 +1,34 @@
1
+ import esphome.codegen as cg
2
+ from esphome.components import i2c, sensor
3
+ import esphome.config_validation as cv
4
+ from esphome.const import (
5
+ DEVICE_CLASS_TEMPERATURE,
6
+ STATE_CLASS_MEASUREMENT,
7
+ UNIT_CELSIUS,
8
+ )
9
+
10
+ CODEOWNERS = ["@beormund"]
11
+ DEPENDENCIES = ["i2c"]
12
+
13
+ lm75b_ns = cg.esphome_ns.namespace("lm75b")
14
+ LM75BComponent = lm75b_ns.class_(
15
+ "LM75BComponent", cg.PollingComponent, i2c.I2CDevice, sensor.Sensor
16
+ )
17
+
18
+ CONFIG_SCHEMA = (
19
+ sensor.sensor_schema(
20
+ LM75BComponent,
21
+ unit_of_measurement=UNIT_CELSIUS,
22
+ accuracy_decimals=3,
23
+ device_class=DEVICE_CLASS_TEMPERATURE,
24
+ state_class=STATE_CLASS_MEASUREMENT,
25
+ )
26
+ .extend(cv.polling_component_schema("60s"))
27
+ .extend(i2c.i2c_device_schema(0x48))
28
+ )
29
+
30
+
31
+ async def to_code(config):
32
+ var = await sensor.new_sensor(config)
33
+ await cg.register_component(var, config)
34
+ await i2c.register_i2c_device(var, config)
@@ -5,7 +5,7 @@
5
5
  #include "esphome/core/helpers.h"
6
6
  #include "esphome/core/log.h"
7
7
  #include "esphome/core/preferences.h"
8
- #include <set>
8
+ #include <initializer_list>
9
9
 
10
10
  namespace esphome {
11
11
  namespace lock {
@@ -44,16 +44,22 @@ class LockTraits {
44
44
  bool get_assumed_state() const { return this->assumed_state_; }
45
45
  void set_assumed_state(bool assumed_state) { this->assumed_state_ = assumed_state; }
46
46
 
47
- bool supports_state(LockState state) const { return supported_states_.count(state); }
48
- std::set<LockState> get_supported_states() const { return supported_states_; }
49
- void set_supported_states(std::set<LockState> states) { supported_states_ = std::move(states); }
50
- void add_supported_state(LockState state) { supported_states_.insert(state); }
47
+ bool supports_state(LockState state) const { return supported_states_mask_ & (1 << state); }
48
+ void set_supported_states(std::initializer_list<LockState> states) {
49
+ supported_states_mask_ = 0;
50
+ for (auto state : states) {
51
+ supported_states_mask_ |= (1 << state);
52
+ }
53
+ }
54
+ uint8_t get_supported_states_mask() const { return supported_states_mask_; }
55
+ void set_supported_states_mask(uint8_t mask) { supported_states_mask_ = mask; }
56
+ void add_supported_state(LockState state) { supported_states_mask_ |= (1 << state); }
51
57
 
52
58
  protected:
53
59
  bool supports_open_{false};
54
60
  bool requires_code_{false};
55
61
  bool assumed_state_{false};
56
- std::set<LockState> supported_states_ = {LOCK_STATE_NONE, LOCK_STATE_LOCKED, LOCK_STATE_UNLOCKED};
62
+ uint8_t supported_states_mask_{(1 << LOCK_STATE_NONE) | (1 << LOCK_STATE_LOCKED) | (1 << LOCK_STATE_UNLOCKED)};
57
63
  };
58
64
 
59
65
  /** This class is used to encode all control actions on a lock device.
@@ -95,6 +95,7 @@ DEFAULT = "DEFAULT"
95
95
 
96
96
  CONF_INITIAL_LEVEL = "initial_level"
97
97
  CONF_LOGGER_ID = "logger_id"
98
+ CONF_RUNTIME_TAG_LEVELS = "runtime_tag_levels"
98
99
  CONF_TASK_LOG_BUFFER_SIZE = "task_log_buffer_size"
99
100
 
100
101
  UART_SELECTION_ESP32 = {
@@ -117,8 +118,6 @@ UART_SELECTION_LIBRETINY = {
117
118
  COMPONENT_RTL87XX: [DEFAULT, UART0, UART1, UART2],
118
119
  }
119
120
 
120
- ESP_ARDUINO_UNSUPPORTED_USB_UARTS = [USB_SERIAL_JTAG]
121
-
122
121
  UART_SELECTION_RP2040 = [USB_CDC, UART0, UART1]
123
122
 
124
123
  UART_SELECTION_NRF52 = [USB_CDC, UART0]
@@ -153,13 +152,7 @@ is_log_level = cv.one_of(*LOG_LEVELS, upper=True)
153
152
 
154
153
  def uart_selection(value):
155
154
  if CORE.is_esp32:
156
- if CORE.using_arduino and value.upper() in ESP_ARDUINO_UNSUPPORTED_USB_UARTS:
157
- raise cv.Invalid(f"Arduino framework does not support {value}.")
158
155
  variant = get_esp32_variant()
159
- if CORE.using_esp_idf and variant == VARIANT_ESP32C3 and value == USB_CDC:
160
- raise cv.Invalid(
161
- f"{value} is not supported for variant {variant} when using ESP-IDF."
162
- )
163
156
  if variant in UART_SELECTION_ESP32:
164
157
  return cv.one_of(*UART_SELECTION_ESP32[variant], upper=True)(value)
165
158
  if CORE.is_esp8266:
@@ -226,14 +219,11 @@ CONFIG_SCHEMA = cv.All(
226
219
  esp8266=UART0,
227
220
  esp32=UART0,
228
221
  esp32_s2=USB_CDC,
229
- esp32_s3_arduino=USB_CDC,
230
- esp32_s3_idf=USB_SERIAL_JTAG,
231
- esp32_c3_arduino=USB_CDC,
232
- esp32_c3_idf=USB_SERIAL_JTAG,
233
- esp32_c5_idf=USB_SERIAL_JTAG,
234
- esp32_c6_arduino=USB_CDC,
235
- esp32_c6_idf=USB_SERIAL_JTAG,
236
- esp32_p4_idf=USB_SERIAL_JTAG,
222
+ esp32_s3=USB_SERIAL_JTAG,
223
+ esp32_c3=USB_SERIAL_JTAG,
224
+ esp32_c5=USB_SERIAL_JTAG,
225
+ esp32_c6=USB_SERIAL_JTAG,
226
+ esp32_p4=USB_SERIAL_JTAG,
237
227
  rp2040=USB_CDC,
238
228
  bk72xx=DEFAULT,
239
229
  ln882x=DEFAULT,
@@ -260,6 +250,7 @@ CONFIG_SCHEMA = cv.All(
260
250
  }
261
251
  ),
262
252
  cv.Optional(CONF_INITIAL_LEVEL): is_log_level,
253
+ cv.Optional(CONF_RUNTIME_TAG_LEVELS, default=False): cv.boolean,
263
254
  cv.Optional(CONF_ON_MESSAGE): automation.validate_automation(
264
255
  {
265
256
  cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(LoggerMessageTrigger),
@@ -302,8 +293,12 @@ async def to_code(config):
302
293
  )
303
294
  cg.add(log.pre_setup())
304
295
 
305
- for tag, log_level in config[CONF_LOGS].items():
306
- cg.add(log.set_log_level(tag, LOG_LEVELS[log_level]))
296
+ # Enable runtime tag levels if logs are configured or explicitly enabled
297
+ logs_config = config[CONF_LOGS]
298
+ if logs_config or config[CONF_RUNTIME_TAG_LEVELS]:
299
+ cg.add_define("USE_LOGGER_RUNTIME_TAG_LEVELS")
300
+ for tag, log_level in logs_config.items():
301
+ cg.add(log.set_log_level(tag, LOG_LEVELS[log_level]))
307
302
 
308
303
  cg.add_define("USE_LOGGER")
309
304
  this_severity = LOG_LEVEL_SEVERITY.index(level)
@@ -346,15 +341,7 @@ async def to_code(config):
346
341
  if config.get(CONF_ESP8266_STORE_LOG_STRINGS_IN_FLASH):
347
342
  cg.add_build_flag("-DUSE_STORE_LOG_STR_IN_FLASH")
348
343
 
349
- if CORE.using_arduino and config[CONF_HARDWARE_UART] == USB_CDC:
350
- cg.add_build_flag("-DARDUINO_USB_CDC_ON_BOOT=1")
351
- if CORE.is_esp32 and get_esp32_variant() in (
352
- VARIANT_ESP32C3,
353
- VARIANT_ESP32C6,
354
- ):
355
- cg.add_build_flag("-DARDUINO_USB_MODE=1")
356
-
357
- if CORE.using_esp_idf:
344
+ if CORE.is_esp32:
358
345
  if config[CONF_HARDWARE_UART] == USB_CDC:
359
346
  add_idf_sdkconfig_option("CONFIG_ESP_CONSOLE_USB_CDC", True)
360
347
  elif config[CONF_HARDWARE_UART] == USB_SERIAL_JTAG:
@@ -462,6 +449,7 @@ async def logger_set_level_to_code(config, action_id, template_arg, args):
462
449
  level = LOG_LEVELS[config[CONF_LEVEL]]
463
450
  logger = await cg.get_variable(config[CONF_LOGGER_ID])
464
451
  if tag := config.get(CONF_TAG):
452
+ cg.add_define("USE_LOGGER_RUNTIME_TAG_LEVELS")
465
453
  text = str(cg.statement(logger.set_log_level(tag, level)))
466
454
  else:
467
455
  text = str(cg.statement(logger.set_log_level(level)))