esphome 2025.6.2__py3-none-any.whl → 2025.7.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 (601) hide show
  1. esphome/__main__.py +1 -3
  2. esphome/codegen.py +2 -0
  3. esphome/components/ac_dimmer/ac_dimmer.cpp +6 -6
  4. esphome/components/adc/__init__.py +25 -1
  5. esphome/components/adc/adc_sensor.h +11 -11
  6. esphome/components/adc/adc_sensor_common.cpp +1 -1
  7. esphome/components/adc/adc_sensor_esp32.cpp +16 -8
  8. esphome/components/ade7880/ade7880.h +0 -2
  9. esphome/components/ads1115/ads1115.h +0 -1
  10. esphome/components/ads1118/ads1118.h +0 -1
  11. esphome/components/ags10/ags10.h +0 -2
  12. esphome/components/aic3204/aic3204.h +0 -1
  13. esphome/components/alarm_control_panel/__init__.py +5 -2
  14. esphome/components/alpha3/alpha3.h +0 -1
  15. esphome/components/am43/cover/am43_cover.h +0 -1
  16. esphome/components/am43/sensor/am43_sensor.h +0 -1
  17. esphome/components/analog_threshold/analog_threshold_binary_sensor.h +0 -2
  18. esphome/components/anova/anova.cpp +5 -1
  19. esphome/components/anova/anova.h +0 -1
  20. esphome/components/apds9960/apds9960.cpp +1 -1
  21. esphome/components/api/__init__.py +42 -20
  22. esphome/components/api/api_connection.cpp +318 -391
  23. esphome/components/api/api_connection.h +206 -126
  24. esphome/components/api/api_frame_helper.cpp +89 -124
  25. esphome/components/api/api_frame_helper.h +57 -45
  26. esphome/components/api/api_pb2.cpp +414 -4350
  27. esphome/components/api/api_pb2.h +287 -198
  28. esphome/components/api/api_pb2_dump.cpp +4333 -0
  29. esphome/components/api/api_pb2_service.cpp +180 -425
  30. esphome/components/api/api_pb2_service.h +7 -6
  31. esphome/components/api/api_pb2_size.h +2 -4
  32. esphome/components/api/api_server.cpp +138 -167
  33. esphome/components/api/api_server.h +66 -12
  34. esphome/components/api/client.py +10 -4
  35. esphome/components/api/list_entities.cpp +36 -105
  36. esphome/components/api/list_entities.h +31 -23
  37. esphome/components/api/proto.h +26 -3
  38. esphome/components/api/subscribe_state.cpp +23 -29
  39. esphome/components/api/subscribe_state.h +26 -19
  40. esphome/components/as5600/as5600.h +0 -1
  41. esphome/components/async_tcp/__init__.py +14 -5
  42. esphome/components/atc_mithermometer/atc_mithermometer.h +0 -1
  43. esphome/components/atm90e32/atm90e32.cpp +2 -1
  44. esphome/components/audio/audio_decoder.cpp +1 -1
  45. esphome/components/audio/audio_transfer_buffer.cpp +2 -2
  46. esphome/components/b_parasite/b_parasite.h +0 -1
  47. esphome/components/bedjet/bedjet_hub.cpp +5 -1
  48. esphome/components/bedjet/climate/bedjet_climate.cpp +5 -1
  49. esphome/components/beken_spi_led_strip/led_strip.cpp +4 -2
  50. esphome/components/bh1750/bh1750.cpp +5 -5
  51. esphome/components/binary_sensor/__init__.py +82 -5
  52. esphome/components/binary_sensor/automation.h +19 -1
  53. esphome/components/binary_sensor/binary_sensor.cpp +12 -30
  54. esphome/components/binary_sensor/binary_sensor.h +11 -25
  55. esphome/components/binary_sensor/filter.cpp +29 -24
  56. esphome/components/binary_sensor/filter.h +20 -10
  57. esphome/components/ble_client/output/ble_binary_output.h +0 -1
  58. esphome/components/ble_client/sensor/ble_rssi_sensor.cpp +5 -1
  59. esphome/components/ble_client/sensor/ble_rssi_sensor.h +0 -1
  60. esphome/components/ble_client/sensor/ble_sensor.cpp +5 -1
  61. esphome/components/ble_client/sensor/ble_sensor.h +0 -1
  62. esphome/components/ble_client/switch/ble_switch.h +0 -1
  63. esphome/components/ble_client/text_sensor/ble_text_sensor.cpp +5 -1
  64. esphome/components/ble_client/text_sensor/ble_text_sensor.h +0 -1
  65. esphome/components/ble_presence/ble_presence_device.h +0 -1
  66. esphome/components/ble_rssi/ble_rssi_sensor.h +0 -1
  67. esphome/components/ble_scanner/ble_scanner.h +0 -1
  68. esphome/components/bluetooth_proxy/bluetooth_connection.h +9 -2
  69. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +16 -6
  70. esphome/components/bluetooth_proxy/bluetooth_proxy.h +8 -2
  71. esphome/components/bme680/sensor.py +1 -1
  72. esphome/components/bmp581/bmp581.h +0 -2
  73. esphome/components/button/__init__.py +5 -2
  74. esphome/components/camera/__init__.py +1 -0
  75. esphome/components/camera/camera.cpp +22 -0
  76. esphome/components/camera/camera.h +80 -0
  77. esphome/components/canbus/__init__.py +1 -0
  78. esphome/components/cap1188/cap1188.h +0 -1
  79. esphome/components/captive_portal/__init__.py +12 -2
  80. esphome/components/captive_portal/captive_portal.cpp +12 -2
  81. esphome/components/captive_portal/captive_portal.h +5 -2
  82. esphome/components/ccs811/ccs811.h +0 -2
  83. esphome/components/climate/__init__.py +5 -2
  84. esphome/components/cm1106/sensor.py +2 -2
  85. esphome/components/const/__init__.py +2 -0
  86. esphome/components/copy/binary_sensor/copy_binary_sensor.h +0 -1
  87. esphome/components/copy/button/copy_button.h +0 -1
  88. esphome/components/copy/cover/copy_cover.h +0 -1
  89. esphome/components/copy/fan/copy_fan.h +0 -1
  90. esphome/components/copy/lock/copy_lock.h +0 -1
  91. esphome/components/copy/number/copy_number.h +0 -1
  92. esphome/components/copy/select/copy_select.h +0 -1
  93. esphome/components/copy/sensor/copy_sensor.h +0 -1
  94. esphome/components/copy/switch/copy_switch.h +0 -1
  95. esphome/components/copy/text/copy_text.h +0 -1
  96. esphome/components/copy/text_sensor/copy_text_sensor.h +0 -1
  97. esphome/components/cover/__init__.py +5 -2
  98. esphome/components/cs5460a/cs5460a.h +0 -1
  99. esphome/components/datetime/__init__.py +4 -2
  100. esphome/components/debug/__init__.py +20 -0
  101. esphome/components/deep_sleep/__init__.py +43 -9
  102. esphome/components/demo/__init__.py +2 -2
  103. esphome/components/display/display.cpp +4 -3
  104. esphome/components/display/display.h +0 -2
  105. esphome/components/display/display_buffer.cpp +1 -1
  106. esphome/components/ds2484/__init__.py +1 -0
  107. esphome/components/ds2484/ds2484.cpp +209 -0
  108. esphome/components/ds2484/ds2484.h +43 -0
  109. esphome/components/ds2484/one_wire.py +37 -0
  110. esphome/components/duty_time/duty_time_sensor.h +0 -1
  111. esphome/components/ens160_base/ens160_base.h +0 -1
  112. esphome/components/es7210/es7210.h +0 -1
  113. esphome/components/es7243e/es7243e.h +0 -1
  114. esphome/components/es8156/es8156.h +0 -1
  115. esphome/components/es8311/es8311.h +0 -1
  116. esphome/components/es8388/es8388.h +0 -1
  117. esphome/components/esp32/__init__.py +102 -135
  118. esphome/components/esp32/core.cpp +0 -4
  119. esphome/components/esp32/gpio.h +1 -1
  120. esphome/components/esp32/helpers.cpp +69 -0
  121. esphome/components/esp32_ble/ble.cpp +5 -6
  122. esphome/components/esp32_ble/ble.h +29 -14
  123. esphome/components/esp32_ble/ble_event.h +6 -6
  124. esphome/components/esp32_ble_client/ble_client_base.cpp +21 -6
  125. esphome/components/esp32_ble_client/ble_client_base.h +24 -9
  126. esphome/components/esp32_ble_tracker/__init__.py +2 -8
  127. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +5 -5
  128. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +11 -7
  129. esphome/components/esp32_camera/__init__.py +111 -97
  130. esphome/components/esp32_camera/esp32_camera.cpp +41 -31
  131. esphome/components/esp32_camera/esp32_camera.h +35 -30
  132. esphome/components/esp32_camera_web_server/__init__.py +2 -1
  133. esphome/components/esp32_camera_web_server/camera_web_server.cpp +8 -8
  134. esphome/components/esp32_camera_web_server/camera_web_server.h +3 -3
  135. esphome/components/esp32_hall/sensor.py +2 -21
  136. esphome/components/esp32_hosted/__init__.py +101 -0
  137. esphome/components/esp32_hosted/esp32_hosted.py.script +12 -0
  138. esphome/components/esp32_improv/esp32_improv_component.cpp +3 -0
  139. esphome/components/esp32_rmt/__init__.py +0 -58
  140. esphome/components/esp32_rmt_led_strip/led_strip.cpp +77 -63
  141. esphome/components/esp32_rmt_led_strip/led_strip.h +11 -17
  142. esphome/components/esp32_rmt_led_strip/light.py +14 -76
  143. esphome/components/esp32_touch/esp32_touch.h +174 -28
  144. esphome/components/esp32_touch/esp32_touch_common.cpp +162 -0
  145. esphome/components/esp32_touch/esp32_touch_v1.cpp +238 -0
  146. esphome/components/esp32_touch/esp32_touch_v2.cpp +397 -0
  147. esphome/components/esp8266/__init__.py +1 -0
  148. esphome/components/esp8266/gpio.cpp +10 -10
  149. esphome/components/esp8266/helpers.cpp +31 -0
  150. esphome/components/esphome/ota/__init__.py +1 -0
  151. esphome/components/esphome/ota/ota_esphome.cpp +24 -19
  152. esphome/components/ethernet/__init__.py +42 -23
  153. esphome/components/ethernet/esp_eth_phy_jl1101.c +0 -16
  154. esphome/components/ethernet/ethernet_component.cpp +69 -29
  155. esphome/components/ethernet/ethernet_component.h +18 -10
  156. esphome/components/event/__init__.py +5 -2
  157. esphome/components/ezo/ezo.h +0 -1
  158. esphome/components/ezo_pmp/ezo_pmp.h +0 -1
  159. esphome/components/fan/__init__.py +5 -2
  160. esphome/components/feedback/feedback_cover.h +0 -1
  161. esphome/components/font/__init__.py +92 -82
  162. esphome/components/font/font.cpp +9 -2
  163. esphome/components/font/font.h +20 -5
  164. esphome/components/fs3000/fs3000.h +0 -1
  165. esphome/components/gcja5/gcja5.h +0 -1
  166. esphome/components/gl_r01_i2c/__init__.py +0 -0
  167. esphome/components/gl_r01_i2c/gl_r01_i2c.cpp +68 -0
  168. esphome/components/gl_r01_i2c/gl_r01_i2c.h +22 -0
  169. esphome/components/gl_r01_i2c/sensor.py +36 -0
  170. esphome/components/gp8403/gp8403.h +0 -1
  171. esphome/components/gpio/binary_sensor/__init__.py +17 -0
  172. esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp +77 -3
  173. esphome/components/gpio/binary_sensor/gpio_binary_sensor.h +40 -0
  174. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.h +0 -2
  175. esphome/components/he60r/he60r.h +0 -1
  176. esphome/components/heatpumpir/climate.py +2 -1
  177. esphome/components/heatpumpir/heatpumpir.cpp +1 -0
  178. esphome/components/heatpumpir/heatpumpir.h +1 -0
  179. esphome/components/honeywellabp2_i2c/honeywellabp2.h +0 -1
  180. esphome/components/host/__init__.py +2 -1
  181. esphome/components/host/helpers.cpp +57 -0
  182. esphome/components/http_request/__init__.py +19 -1
  183. esphome/components/http_request/http_request.h +1 -1
  184. esphome/components/http_request/http_request_arduino.cpp +0 -1
  185. esphome/components/http_request/http_request_arduino.h +1 -0
  186. esphome/components/http_request/http_request_idf.cpp +0 -1
  187. esphome/components/http_request/ota/ota_http_request.cpp +1 -1
  188. esphome/components/http_request/update/http_request_update.cpp +28 -9
  189. esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +3 -9
  190. esphome/components/hydreon_rgxx/sensor.py +1 -1
  191. esphome/components/i2c/__init__.py +23 -11
  192. esphome/components/i2c/i2c_bus.h +8 -1
  193. esphome/components/i2c/i2c_bus_arduino.cpp +4 -3
  194. esphome/components/i2c/i2c_bus_arduino.h +6 -3
  195. esphome/components/i2c/i2c_bus_esp_idf.h +5 -3
  196. esphome/components/i2c_device/i2c_device.h +0 -1
  197. esphome/components/i2s_audio/__init__.py +2 -10
  198. esphome/components/i2s_audio/i2s_audio.cpp +1 -5
  199. esphome/components/i2s_audio/media_player/__init__.py +2 -2
  200. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +2 -2
  201. esphome/components/iaqcore/iaqcore.h +0 -2
  202. esphome/components/image/__init__.py +123 -24
  203. esphome/components/improv_serial/improv_serial_component.cpp +0 -4
  204. esphome/components/ina219/ina219.cpp +7 -0
  205. esphome/components/ina219/ina219.h +1 -0
  206. esphome/components/ina260/ina260.h +0 -2
  207. esphome/components/inkbird_ibsth1_mini/inkbird_ibsth1_mini.h +0 -1
  208. esphome/components/inkplate6/display.py +15 -0
  209. esphome/components/inkplate6/inkplate.cpp +2 -2
  210. esphome/components/integration/integration_sensor.h +0 -1
  211. esphome/components/internal_temperature/internal_temperature.cpp +8 -27
  212. esphome/components/internal_temperature/sensor.py +0 -26
  213. esphome/components/interval/interval.h +0 -2
  214. esphome/components/ld2410/button/__init__.py +3 -3
  215. esphome/components/ld2410/button/factory_reset_button.cpp +9 -0
  216. esphome/components/ld2410/button/{reset_button.h → factory_reset_button.h} +2 -2
  217. esphome/components/ld2410/ld2410.cpp +430 -261
  218. esphome/components/ld2410/ld2410.h +44 -146
  219. esphome/components/ld2410/number/__init__.py +2 -2
  220. esphome/components/ld2410/sensor.py +1 -1
  221. esphome/components/ld2410/switch/__init__.py +1 -1
  222. esphome/components/ld2420/ld2420.cpp +196 -100
  223. esphome/components/ld2420/ld2420.h +46 -118
  224. esphome/components/ld2420/number/__init__.py +2 -2
  225. esphome/components/ld2420/sensor/__init__.py +6 -2
  226. esphome/components/ld2420/sensor/ld2420_sensor.h +1 -1
  227. esphome/components/ld2450/button/__init__.py +3 -3
  228. esphome/components/ld2450/button/factory_reset_button.cpp +9 -0
  229. esphome/components/ld2450/button/{reset_button.h → factory_reset_button.h} +2 -2
  230. esphome/components/ld2450/ld2450.cpp +384 -232
  231. esphome/components/ld2450/ld2450.h +60 -69
  232. esphome/components/ld2450/switch/__init__.py +1 -1
  233. esphome/components/ledc/ledc_output.cpp +1 -63
  234. esphome/components/libretiny/__init__.py +4 -3
  235. esphome/components/libretiny/const.py +5 -0
  236. esphome/components/libretiny/generate_components.py +1 -0
  237. esphome/components/libretiny/helpers.cpp +35 -0
  238. esphome/components/libretiny/lt_component.cpp +5 -3
  239. esphome/components/light/__init__.py +4 -2
  240. esphome/components/light/addressable_light.h +3 -3
  241. esphome/components/light/light_call.cpp +180 -243
  242. esphome/components/light/light_call.h +72 -20
  243. esphome/components/light/light_color_values.h +14 -14
  244. esphome/components/light/light_state.h +15 -13
  245. esphome/components/light/transformers.h +2 -2
  246. esphome/components/ln882x/__init__.py +52 -0
  247. esphome/components/ln882x/boards.py +285 -0
  248. esphome/components/lock/__init__.py +5 -2
  249. esphome/components/logger/__init__.py +40 -3
  250. esphome/components/logger/logger.cpp +47 -12
  251. esphome/components/logger/logger.h +80 -49
  252. esphome/components/logger/logger_esp32.cpp +3 -3
  253. esphome/components/lps22/__init__.py +0 -0
  254. esphome/components/lps22/lps22.cpp +75 -0
  255. esphome/components/lps22/lps22.h +27 -0
  256. esphome/components/lps22/sensor.py +58 -0
  257. esphome/components/ltr390/ltr390.h +0 -1
  258. esphome/components/ltr501/ltr501.h +0 -1
  259. esphome/components/ltr_als_ps/ltr_als_ps.h +0 -1
  260. esphome/components/lvgl/__init__.py +1 -1
  261. esphome/components/lvgl/schemas.py +66 -6
  262. esphome/components/lvgl/styles.py +24 -16
  263. esphome/components/lvgl/widgets/__init__.py +12 -2
  264. esphome/components/lvgl/widgets/lv_bar.py +40 -19
  265. esphome/components/m5stack_8angle/light/m5stack_8angle_light.cpp +1 -1
  266. esphome/components/max9611/max9611.h +0 -1
  267. esphome/components/mcp23016/__init__.py +1 -1
  268. esphome/components/mcp23xxx_base/__init__.py +1 -1
  269. esphome/components/mcp4461/__init__.py +1 -1
  270. esphome/components/mcp4461/output/__init__.py +3 -2
  271. esphome/components/mcp9600/mcp9600.h +0 -2
  272. esphome/components/md5/md5.cpp +3 -3
  273. esphome/components/md5/md5.h +1 -6
  274. esphome/components/mdns/__init__.py +22 -11
  275. esphome/components/media_player/__init__.py +4 -3
  276. esphome/components/micro_wake_word/__init__.py +1 -5
  277. esphome/components/micro_wake_word/streaming_model.cpp +2 -2
  278. esphome/components/microphone/microphone.cpp +7 -9
  279. esphome/components/microphone/microphone.h +0 -2
  280. esphome/components/mipi_spi/display.py +1 -0
  281. esphome/components/mmc5603/mmc5603.cpp +1 -1
  282. esphome/components/modbus/modbus.cpp +33 -15
  283. esphome/components/modbus/modbus.h +9 -0
  284. esphome/components/modbus_controller/__init__.py +42 -10
  285. esphome/components/modbus_controller/modbus_controller.cpp +92 -11
  286. esphome/components/modbus_controller/modbus_controller.h +61 -7
  287. esphome/components/mopeka_pro_check/mopeka_pro_check.h +0 -1
  288. esphome/components/mopeka_std_check/mopeka_std_check.h +0 -1
  289. esphome/components/mpl3115a2/mpl3115a2.h +0 -2
  290. esphome/components/mqtt/__init__.py +16 -0
  291. esphome/components/mqtt/mqtt_backend.h +2 -1
  292. esphome/components/mqtt/mqtt_backend_esp32.cpp +126 -45
  293. esphome/components/mqtt/mqtt_backend_esp32.h +106 -4
  294. esphome/components/mqtt/mqtt_client.cpp +15 -9
  295. esphome/components/mqtt/mqtt_client.h +8 -3
  296. esphome/components/ms8607/ms8607.h +0 -1
  297. esphome/components/neopixelbus/light.py +4 -1
  298. esphome/components/neopixelbus/neopixelbus_light.h +1 -1
  299. esphome/components/network/__init__.py +4 -1
  300. esphome/components/network/ip_address.h +1 -0
  301. esphome/components/nextion/__init__.py +16 -0
  302. esphome/components/nextion/base_component.py +1 -0
  303. esphome/components/nextion/binary_sensor/nextion_binarysensor.cpp +1 -1
  304. esphome/components/nextion/display.py +14 -4
  305. esphome/components/nextion/nextion.cpp +166 -101
  306. esphome/components/nextion/nextion.h +84 -53
  307. esphome/components/nextion/nextion_commands.cpp +11 -10
  308. esphome/components/nextion/nextion_component.cpp +28 -28
  309. esphome/components/nextion/nextion_component.h +53 -18
  310. esphome/components/nextion/nextion_component_base.h +3 -0
  311. esphome/components/nextion/nextion_upload.cpp +36 -0
  312. esphome/components/nextion/nextion_upload_arduino.cpp +10 -35
  313. esphome/components/nextion/nextion_upload_idf.cpp +9 -33
  314. esphome/components/nextion/sensor/nextion_sensor.cpp +1 -1
  315. esphome/components/nextion/switch/nextion_switch.cpp +1 -1
  316. esphome/components/nextion/text_sensor/nextion_textsensor.cpp +1 -1
  317. esphome/components/nfc/nfc.cpp +3 -22
  318. esphome/components/nfc/nfc.h +3 -3
  319. esphome/components/number/__init__.py +5 -2
  320. esphome/components/online_image/__init__.py +5 -0
  321. esphome/components/online_image/online_image.cpp +6 -2
  322. esphome/components/online_image/online_image.h +4 -1
  323. esphome/components/opentherm/opentherm.cpp +7 -12
  324. esphome/components/openthread/__init__.py +47 -40
  325. esphome/components/openthread/const.py +1 -0
  326. esphome/components/openthread/openthread_esp.cpp +27 -5
  327. esphome/components/opt3001/__init__.py +0 -0
  328. esphome/components/opt3001/opt3001.cpp +122 -0
  329. esphome/components/opt3001/opt3001.h +27 -0
  330. esphome/components/opt3001/sensor.py +35 -0
  331. esphome/components/ota/__init__.py +17 -0
  332. esphome/components/ota/ota_backend.h +27 -1
  333. esphome/components/ota/ota_backend_arduino_esp32.cpp +12 -2
  334. esphome/components/ota/ota_backend_arduino_esp32.h +3 -0
  335. esphome/components/ota/ota_backend_arduino_esp8266.cpp +18 -4
  336. esphome/components/ota/ota_backend_arduino_esp8266.h +3 -0
  337. esphome/components/ota/ota_backend_arduino_libretiny.cpp +12 -2
  338. esphome/components/ota/ota_backend_arduino_libretiny.h +3 -0
  339. esphome/components/ota/ota_backend_arduino_rp2040.cpp +9 -2
  340. esphome/components/ota/ota_backend_arduino_rp2040.h +3 -0
  341. esphome/components/ota/ota_backend_esp_idf.cpp +10 -16
  342. esphome/components/ota/ota_backend_esp_idf.h +1 -0
  343. esphome/components/packages/__init__.py +5 -2
  344. esphome/components/packet_transport/binary_sensor.py +61 -4
  345. esphome/components/packet_transport/packet_transport.cpp +31 -1
  346. esphome/components/packet_transport/packet_transport.h +11 -5
  347. esphome/components/pcf8574/__init__.py +1 -1
  348. esphome/components/pi4ioe5v6408/__init__.py +84 -0
  349. esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +171 -0
  350. esphome/components/pi4ioe5v6408/pi4ioe5v6408.h +70 -0
  351. esphome/components/pmsa003i/pmsa003i.h +0 -1
  352. esphome/components/pmsx003/pmsx003.h +0 -1
  353. esphome/components/pn7150/pn7150.cpp +7 -7
  354. esphome/components/pn7150/pn7150.h +0 -1
  355. esphome/components/pn7160/pn7160.cpp +7 -7
  356. esphome/components/pn7160/pn7160.h +0 -1
  357. esphome/components/preferences/syncer.h +2 -0
  358. esphome/components/prometheus/prometheus_handler.h +1 -1
  359. esphome/components/psram/psram.cpp +0 -20
  360. esphome/components/pulse_counter/pulse_counter_sensor.h +0 -1
  361. esphome/components/pulse_meter/pulse_meter_sensor.cpp +8 -4
  362. esphome/components/pulse_width/pulse_width.h +0 -1
  363. esphome/components/pvvx_mithermometer/display/pvvx_display.cpp +0 -4
  364. esphome/components/pvvx_mithermometer/display/pvvx_display.h +0 -2
  365. esphome/components/pvvx_mithermometer/pvvx_mithermometer.h +0 -1
  366. esphome/components/qr_code/__init__.py +13 -10
  367. esphome/components/qwiic_pir/qwiic_pir.h +0 -1
  368. esphome/components/radon_eye_ble/radon_eye_listener.cpp +1 -1
  369. esphome/components/rc522/rc522.h +0 -1
  370. esphome/components/rdm6300/rdm6300.h +0 -2
  371. esphome/components/remote_base/__init__.py +7 -5
  372. esphome/components/remote_base/remote_base.cpp +24 -21
  373. esphome/components/remote_base/remote_base.h +3 -26
  374. esphome/components/remote_receiver/__init__.py +40 -46
  375. esphome/components/remote_receiver/remote_receiver.h +4 -18
  376. esphome/components/remote_receiver/remote_receiver_esp32.cpp +0 -87
  377. esphome/components/remote_receiver/remote_receiver_esp8266.cpp +1 -1
  378. esphome/components/remote_transmitter/__init__.py +42 -43
  379. esphome/components/remote_transmitter/remote_transmitter.h +2 -14
  380. esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +0 -77
  381. esphome/components/resistance/resistance_sensor.h +0 -1
  382. esphome/components/rp2040/__init__.py +1 -0
  383. esphome/components/rp2040/helpers.cpp +55 -0
  384. esphome/components/rp2040_pio_led_strip/led_strip.cpp +2 -2
  385. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +0 -4
  386. esphome/components/rtttl/__init__.py +4 -4
  387. esphome/components/rtttl/rtttl.cpp +10 -1
  388. esphome/components/ruuvitag/ruuvitag.h +0 -1
  389. esphome/components/safe_mode/safe_mode.cpp +2 -0
  390. esphome/components/safe_mode/safe_mode.h +4 -1
  391. esphome/components/scd30/scd30.h +0 -1
  392. esphome/components/scd30/sensor.py +2 -2
  393. esphome/components/scd4x/scd4x.cpp +61 -54
  394. esphome/components/scd4x/scd4x.h +17 -15
  395. esphome/components/scd4x/sensor.py +4 -4
  396. esphome/components/script/script.h +0 -2
  397. esphome/components/sdp3x/sensor.py +1 -1
  398. esphome/components/select/__init__.py +5 -2
  399. esphome/components/sen5x/sen5x.h +0 -1
  400. esphome/components/senseair/senseair.h +0 -1
  401. esphome/components/sensor/__init__.py +4 -2
  402. esphome/components/sensor/filter.cpp +1 -1
  403. esphome/components/sensor/sensor.cpp +12 -6
  404. esphome/components/sensor/sensor.h +13 -5
  405. esphome/components/servo/servo.h +0 -1
  406. esphome/components/sfa30/sfa30.h +0 -1
  407. esphome/components/sgp30/sgp30.h +0 -1
  408. esphome/components/sgp4x/sgp4x.h +0 -1
  409. esphome/components/shelly_dimmer/stm32flash.cpp +1 -2
  410. esphome/components/sht4x/sht4x.h +0 -1
  411. esphome/components/sm300d2/sm300d2.h +0 -2
  412. esphome/components/smt100/sensor.py +8 -4
  413. esphome/components/smt100/smt100.cpp +5 -5
  414. esphome/components/smt100/smt100.h +3 -3
  415. esphome/components/sn74hc595/__init__.py +1 -1
  416. esphome/components/sn74hc595/sn74hc595.cpp +5 -4
  417. esphome/components/sntp/sntp_component.cpp +9 -3
  418. esphome/components/sntp/time.py +2 -0
  419. esphome/components/socket/__init__.py +17 -0
  420. esphome/components/spi/__init__.py +27 -6
  421. esphome/components/spi/spi.cpp +3 -2
  422. esphome/components/spi/spi.h +9 -3
  423. esphome/components/spi/spi_arduino.cpp +3 -5
  424. esphome/components/spi/spi_esp_idf.cpp +40 -21
  425. esphome/components/spi_led_strip/spi_led_strip.cpp +1 -1
  426. esphome/components/sps30/sps30.h +0 -1
  427. esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
  428. esphome/components/st7701s/st7701s.cpp +0 -4
  429. esphome/components/status/status_binary_sensor.h +0 -2
  430. esphome/components/substitutions/__init__.py +76 -19
  431. esphome/components/substitutions/jinja.py +99 -0
  432. esphome/components/sun/sun.cpp +3 -4
  433. esphome/components/switch/__init__.py +5 -2
  434. esphome/components/switch/binary_sensor/switch_binary_sensor.h +0 -1
  435. esphome/components/sx126x/__init__.py +317 -0
  436. esphome/components/sx126x/automation.h +62 -0
  437. esphome/components/sx126x/packet_transport/__init__.py +26 -0
  438. esphome/components/sx126x/packet_transport/sx126x_transport.cpp +26 -0
  439. esphome/components/sx126x/packet_transport/sx126x_transport.h +25 -0
  440. esphome/components/sx126x/sx126x.cpp +523 -0
  441. esphome/components/sx126x/sx126x.h +140 -0
  442. esphome/components/sx126x/sx126x_reg.h +163 -0
  443. esphome/components/sx127x/__init__.py +325 -0
  444. esphome/components/sx127x/automation.h +62 -0
  445. esphome/components/sx127x/packet_transport/__init__.py +26 -0
  446. esphome/components/sx127x/packet_transport/sx127x_transport.cpp +26 -0
  447. esphome/components/sx127x/packet_transport/sx127x_transport.h +25 -0
  448. esphome/components/sx127x/sx127x.cpp +498 -0
  449. esphome/components/sx127x/sx127x.h +128 -0
  450. esphome/components/sx127x/sx127x_reg.h +295 -0
  451. esphome/components/syslog/esphome_syslog.cpp +5 -3
  452. esphome/components/syslog/esphome_syslog.h +1 -1
  453. esphome/components/tca9555/__init__.py +1 -1
  454. esphome/components/template/binary_sensor/template_binary_sensor.cpp +1 -9
  455. esphome/components/text/__init__.py +5 -2
  456. esphome/components/text_sensor/__init__.py +5 -2
  457. esphome/components/thermostat/thermostat_climate.cpp +34 -31
  458. esphome/components/thermostat/thermostat_climate.h +43 -39
  459. esphome/components/time/__init__.py +16 -2
  460. esphome/components/time/real_time_clock.cpp +4 -0
  461. esphome/components/time/real_time_clock.h +5 -1
  462. esphome/components/tlc5971/tlc5971.cpp +4 -1
  463. esphome/components/tmp1075/tmp1075.h +0 -2
  464. esphome/components/tof10120/tof10120_sensor.h +0 -1
  465. esphome/components/tormatic/tormatic_cover.h +0 -1
  466. esphome/components/total_daily_energy/total_daily_energy.h +0 -1
  467. esphome/components/tsl2591/tsl2591.cpp +1 -1
  468. esphome/components/ttp229_bsf/ttp229_bsf.h +0 -1
  469. esphome/components/ttp229_lsf/ttp229_lsf.h +0 -1
  470. esphome/components/tx20/tx20.cpp +2 -2
  471. esphome/components/uart/__init__.py +18 -0
  472. esphome/components/uart/uart_component_esp_idf.cpp +1 -5
  473. esphome/components/update/__init__.py +5 -2
  474. esphome/components/update/update_entity.h +8 -0
  475. esphome/components/usb_host/__init__.py +5 -2
  476. esphome/components/valve/__init__.py +5 -2
  477. esphome/components/vbus/vbus.h +0 -1
  478. esphome/components/veml3235/veml3235.h +0 -1
  479. esphome/components/veml7700/veml7700.h +0 -1
  480. esphome/components/vl53l0x/vl53l0x_sensor.h +0 -1
  481. esphome/components/voice_assistant/voice_assistant.cpp +4 -4
  482. esphome/components/watchdog/watchdog.cpp +0 -4
  483. esphome/components/waveshare_epaper/waveshare_epaper.cpp +6 -6
  484. esphome/components/web_server/__init__.py +34 -19
  485. esphome/components/web_server/ota/__init__.py +32 -0
  486. esphome/components/web_server/ota/ota_web_server.cpp +210 -0
  487. esphome/components/web_server/ota/ota_web_server.h +26 -0
  488. esphome/components/web_server/web_server.cpp +311 -430
  489. esphome/components/web_server/web_server.h +33 -23
  490. esphome/components/web_server/web_server_v1.cpp +4 -5
  491. esphome/components/web_server_base/__init__.py +5 -2
  492. esphome/components/web_server_base/web_server_base.cpp +2 -94
  493. esphome/components/web_server_base/web_server_base.h +5 -25
  494. esphome/components/web_server_idf/multipart.cpp +254 -0
  495. esphome/components/web_server_idf/multipart.h +86 -0
  496. esphome/components/web_server_idf/utils.cpp +32 -0
  497. esphome/components/web_server_idf/utils.h +10 -0
  498. esphome/components/web_server_idf/web_server_idf.cpp +162 -16
  499. esphome/components/web_server_idf/web_server_idf.h +11 -10
  500. esphome/components/wiegand/wiegand.cpp +2 -2
  501. esphome/components/wifi/__init__.py +18 -0
  502. esphome/components/wifi/wifi_component.cpp +17 -22
  503. esphome/components/wifi/wifi_component.h +27 -23
  504. esphome/components/wifi/wifi_component_esp32_arduino.cpp +52 -59
  505. esphome/components/wifi/wifi_component_esp8266.cpp +46 -46
  506. esphome/components/wifi/wifi_component_esp_idf.cpp +35 -36
  507. esphome/components/wifi/wifi_component_libretiny.cpp +26 -27
  508. esphome/components/wifi/wifi_component_pico_w.cpp +3 -3
  509. esphome/components/wifi_info/wifi_info_text_sensor.cpp +6 -6
  510. esphome/components/wireguard/__init__.py +2 -11
  511. esphome/components/xiaomi_ble/xiaomi_ble.cpp +13 -1
  512. esphome/components/xiaomi_ble/xiaomi_ble.h +1 -0
  513. esphome/components/xiaomi_cgd1/xiaomi_cgd1.h +0 -1
  514. esphome/components/xiaomi_cgdk2/xiaomi_cgdk2.h +0 -1
  515. esphome/components/xiaomi_cgg1/xiaomi_cgg1.h +0 -1
  516. esphome/components/xiaomi_cgpr1/xiaomi_cgpr1.h +0 -1
  517. esphome/components/xiaomi_gcls002/xiaomi_gcls002.h +0 -1
  518. esphome/components/xiaomi_hhccjcy01/xiaomi_hhccjcy01.h +0 -1
  519. esphome/components/xiaomi_hhccjcy10/xiaomi_hhccjcy10.h +0 -1
  520. esphome/components/xiaomi_hhccpot002/xiaomi_hhccpot002.h +0 -1
  521. esphome/components/xiaomi_jqjcy01ym/xiaomi_jqjcy01ym.h +0 -1
  522. esphome/components/xiaomi_lywsd02/xiaomi_lywsd02.h +0 -1
  523. esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.h +0 -1
  524. esphome/components/xiaomi_lywsd03mmc/xiaomi_lywsd03mmc.h +0 -1
  525. esphome/components/xiaomi_lywsdcgq/xiaomi_lywsdcgq.h +0 -1
  526. esphome/components/xiaomi_mhoc303/xiaomi_mhoc303.h +0 -1
  527. esphome/components/xiaomi_mhoc401/xiaomi_mhoc401.h +0 -1
  528. esphome/components/xiaomi_miscale/xiaomi_miscale.h +0 -1
  529. esphome/components/xiaomi_mjyd02yla/xiaomi_mjyd02yla.h +0 -1
  530. esphome/components/xiaomi_mue4094rt/xiaomi_mue4094rt.h +0 -1
  531. esphome/components/xiaomi_rtcgq02lm/xiaomi_rtcgq02lm.h +0 -1
  532. esphome/components/xiaomi_wx08zm/xiaomi_wx08zm.h +0 -1
  533. esphome/components/xiaomi_xmwsdj04mmc/__init__.py +0 -0
  534. esphome/components/xiaomi_xmwsdj04mmc/sensor.py +77 -0
  535. esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.cpp +77 -0
  536. esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.h +36 -0
  537. esphome/components/zio_ultrasonic/zio_ultrasonic.h +0 -2
  538. esphome/components/zyaura/zyaura.h +0 -1
  539. esphome/config.py +88 -22
  540. esphome/config_helpers.py +74 -1
  541. esphome/config_validation.py +12 -1
  542. esphome/const.py +65 -10
  543. esphome/core/__init__.py +18 -2
  544. esphome/core/application.cpp +163 -10
  545. esphome/core/application.h +145 -165
  546. esphome/core/area.h +19 -0
  547. esphome/core/automation.h +58 -9
  548. esphome/core/color.cpp +3 -5
  549. esphome/core/color.h +16 -16
  550. esphome/core/component.cpp +151 -18
  551. esphome/core/component.h +98 -4
  552. esphome/core/component_iterator.cpp +7 -7
  553. esphome/core/component_iterator.h +9 -7
  554. esphome/core/config.py +155 -6
  555. esphome/core/controller.cpp +4 -2
  556. esphome/core/controller.h +1 -1
  557. esphome/core/datatypes.h +2 -2
  558. esphome/core/defines.h +17 -2
  559. esphome/core/device.h +20 -0
  560. esphome/core/entity_base.cpp +20 -15
  561. esphome/core/entity_base.h +76 -0
  562. esphome/core/entity_helpers.py +162 -1
  563. esphome/core/event_pool.h +81 -0
  564. esphome/core/helpers.cpp +75 -230
  565. esphome/core/helpers.h +164 -104
  566. esphome/core/lock_free_queue.h +151 -0
  567. esphome/core/log.cpp +2 -2
  568. esphome/core/log.h +2 -0
  569. esphome/core/optional.h +5 -0
  570. esphome/core/ring_buffer.cpp +2 -2
  571. esphome/core/scheduler.cpp +278 -103
  572. esphome/core/scheduler.h +157 -17
  573. esphome/core/time.cpp +5 -5
  574. esphome/core/time.h +5 -5
  575. esphome/cpp_generator.py +17 -0
  576. esphome/cpp_helpers.py +0 -22
  577. esphome/cpp_types.py +3 -1
  578. esphome/dashboard/entries.py +1 -1
  579. esphome/dashboard/util/text.py +5 -21
  580. esphome/dashboard/web_server.py +9 -1
  581. esphome/helpers.py +47 -0
  582. esphome/loader.py +15 -1
  583. esphome/pins.py +14 -8
  584. esphome/wizard.py +16 -3
  585. esphome/writer.py +21 -3
  586. esphome/yaml_util.py +0 -2
  587. {esphome-2025.6.2.dist-info → esphome-2025.7.0b1.dist-info}/METADATA +10 -9
  588. {esphome-2025.6.2.dist-info → esphome-2025.7.0b1.dist-info}/RECORD +593 -533
  589. esphome/components/esp32_ble/ble_event_pool.h +0 -72
  590. esphome/components/esp32_ble/queue.h +0 -85
  591. esphome/components/esp32_hall/esp32_hall.cpp +0 -25
  592. esphome/components/esp32_hall/esp32_hall.h +0 -23
  593. esphome/components/esp32_touch/esp32_touch.cpp +0 -355
  594. esphome/components/ld2410/button/reset_button.cpp +0 -9
  595. esphome/components/ld2450/button/reset_button.cpp +0 -9
  596. esphome/components/openthread/tlv.py +0 -65
  597. /esphome/{dashboard/enum.py → enum.py} +0 -0
  598. {esphome-2025.6.2.dist-info → esphome-2025.7.0b1.dist-info}/WHEEL +0 -0
  599. {esphome-2025.6.2.dist-info → esphome-2025.7.0b1.dist-info}/entry_points.txt +0 -0
  600. {esphome-2025.6.2.dist-info → esphome-2025.7.0b1.dist-info}/licenses/LICENSE +0 -0
  601. {esphome-2025.6.2.dist-info → esphome-2025.7.0b1.dist-info}/top_level.txt +0 -0
@@ -2,12 +2,28 @@
2
2
  #include "light_call.h"
3
3
  #include "light_state.h"
4
4
  #include "esphome/core/log.h"
5
+ #include "esphome/core/optional.h"
5
6
 
6
7
  namespace esphome {
7
8
  namespace light {
8
9
 
9
10
  static const char *const TAG = "light";
10
11
 
12
+ // Macro to reduce repetitive setter code
13
+ #define IMPLEMENT_LIGHT_CALL_SETTER(name, type, flag) \
14
+ LightCall &LightCall::set_##name(optional<type>(name)) { \
15
+ if ((name).has_value()) { \
16
+ this->name##_ = (name).value(); \
17
+ } \
18
+ this->set_flag_(flag, (name).has_value()); \
19
+ return *this; \
20
+ } \
21
+ LightCall &LightCall::set_##name(type name) { \
22
+ this->name##_ = name; \
23
+ this->set_flag_(flag, true); \
24
+ return *this; \
25
+ }
26
+
11
27
  static const LogString *color_mode_to_human(ColorMode color_mode) {
12
28
  if (color_mode == ColorMode::UNKNOWN)
13
29
  return LOG_STR("Unknown");
@@ -32,41 +48,43 @@ void LightCall::perform() {
32
48
  const char *name = this->parent_->get_name().c_str();
33
49
  LightColorValues v = this->validate_();
34
50
 
35
- if (this->publish_) {
51
+ if (this->get_publish_()) {
36
52
  ESP_LOGD(TAG, "'%s' Setting:", name);
37
53
 
38
54
  // Only print color mode when it's being changed
39
55
  ColorMode current_color_mode = this->parent_->remote_values.get_color_mode();
40
- if (this->color_mode_.value_or(current_color_mode) != current_color_mode) {
56
+ ColorMode target_color_mode = this->has_color_mode() ? this->color_mode_ : current_color_mode;
57
+ if (target_color_mode != current_color_mode) {
41
58
  ESP_LOGD(TAG, " Color mode: %s", LOG_STR_ARG(color_mode_to_human(v.get_color_mode())));
42
59
  }
43
60
 
44
61
  // Only print state when it's being changed
45
62
  bool current_state = this->parent_->remote_values.is_on();
46
- if (this->state_.value_or(current_state) != current_state) {
63
+ bool target_state = this->has_state() ? this->state_ : current_state;
64
+ if (target_state != current_state) {
47
65
  ESP_LOGD(TAG, " State: %s", ONOFF(v.is_on()));
48
66
  }
49
67
 
50
- if (this->brightness_.has_value()) {
68
+ if (this->has_brightness()) {
51
69
  ESP_LOGD(TAG, " Brightness: %.0f%%", v.get_brightness() * 100.0f);
52
70
  }
53
71
 
54
- if (this->color_brightness_.has_value()) {
72
+ if (this->has_color_brightness()) {
55
73
  ESP_LOGD(TAG, " Color brightness: %.0f%%", v.get_color_brightness() * 100.0f);
56
74
  }
57
- if (this->red_.has_value() || this->green_.has_value() || this->blue_.has_value()) {
75
+ if (this->has_red() || this->has_green() || this->has_blue()) {
58
76
  ESP_LOGD(TAG, " Red: %.0f%%, Green: %.0f%%, Blue: %.0f%%", v.get_red() * 100.0f, v.get_green() * 100.0f,
59
77
  v.get_blue() * 100.0f);
60
78
  }
61
79
 
62
- if (this->white_.has_value()) {
80
+ if (this->has_white()) {
63
81
  ESP_LOGD(TAG, " White: %.0f%%", v.get_white() * 100.0f);
64
82
  }
65
- if (this->color_temperature_.has_value()) {
83
+ if (this->has_color_temperature()) {
66
84
  ESP_LOGD(TAG, " Color temperature: %.1f mireds", v.get_color_temperature());
67
85
  }
68
86
 
69
- if (this->cold_white_.has_value() || this->warm_white_.has_value()) {
87
+ if (this->has_cold_white() || this->has_warm_white()) {
70
88
  ESP_LOGD(TAG, " Cold white: %.0f%%, warm white: %.0f%%", v.get_cold_white() * 100.0f,
71
89
  v.get_warm_white() * 100.0f);
72
90
  }
@@ -74,58 +92,57 @@ void LightCall::perform() {
74
92
 
75
93
  if (this->has_flash_()) {
76
94
  // FLASH
77
- if (this->publish_) {
78
- ESP_LOGD(TAG, " Flash length: %.1fs", *this->flash_length_ / 1e3f);
95
+ if (this->get_publish_()) {
96
+ ESP_LOGD(TAG, " Flash length: %.1fs", this->flash_length_ / 1e3f);
79
97
  }
80
98
 
81
- this->parent_->start_flash_(v, *this->flash_length_, this->publish_);
99
+ this->parent_->start_flash_(v, this->flash_length_, this->get_publish_());
82
100
  } else if (this->has_transition_()) {
83
101
  // TRANSITION
84
- if (this->publish_) {
85
- ESP_LOGD(TAG, " Transition length: %.1fs", *this->transition_length_ / 1e3f);
102
+ if (this->get_publish_()) {
103
+ ESP_LOGD(TAG, " Transition length: %.1fs", this->transition_length_ / 1e3f);
86
104
  }
87
105
 
88
106
  // Special case: Transition and effect can be set when turning off
89
107
  if (this->has_effect_()) {
90
- if (this->publish_) {
108
+ if (this->get_publish_()) {
91
109
  ESP_LOGD(TAG, " Effect: 'None'");
92
110
  }
93
111
  this->parent_->stop_effect_();
94
112
  }
95
113
 
96
- this->parent_->start_transition_(v, *this->transition_length_, this->publish_);
114
+ this->parent_->start_transition_(v, this->transition_length_, this->get_publish_());
97
115
 
98
116
  } else if (this->has_effect_()) {
99
117
  // EFFECT
100
- auto effect = this->effect_;
101
118
  const char *effect_s;
102
- if (effect == 0u) {
119
+ if (this->effect_ == 0u) {
103
120
  effect_s = "None";
104
121
  } else {
105
- effect_s = this->parent_->effects_[*this->effect_ - 1]->get_name().c_str();
122
+ effect_s = this->parent_->effects_[this->effect_ - 1]->get_name().c_str();
106
123
  }
107
124
 
108
- if (this->publish_) {
125
+ if (this->get_publish_()) {
109
126
  ESP_LOGD(TAG, " Effect: '%s'", effect_s);
110
127
  }
111
128
 
112
- this->parent_->start_effect_(*this->effect_);
129
+ this->parent_->start_effect_(this->effect_);
113
130
 
114
131
  // Also set light color values when starting an effect
115
132
  // For example to turn off the light
116
133
  this->parent_->set_immediately_(v, true);
117
134
  } else {
118
135
  // INSTANT CHANGE
119
- this->parent_->set_immediately_(v, this->publish_);
136
+ this->parent_->set_immediately_(v, this->get_publish_());
120
137
  }
121
138
 
122
139
  if (!this->has_transition_()) {
123
140
  this->parent_->target_state_reached_callback_.call();
124
141
  }
125
- if (this->publish_) {
142
+ if (this->get_publish_()) {
126
143
  this->parent_->publish_state();
127
144
  }
128
- if (this->save_) {
145
+ if (this->get_save_()) {
129
146
  this->parent_->save_remote_values_();
130
147
  }
131
148
  }
@@ -135,82 +152,80 @@ LightColorValues LightCall::validate_() {
135
152
  auto traits = this->parent_->get_traits();
136
153
 
137
154
  // Color mode check
138
- if (this->color_mode_.has_value() && !traits.supports_color_mode(this->color_mode_.value())) {
139
- ESP_LOGW(TAG, "'%s' - This light does not support color mode %s!", name,
140
- LOG_STR_ARG(color_mode_to_human(this->color_mode_.value())));
141
- this->color_mode_.reset();
155
+ if (this->has_color_mode() && !traits.supports_color_mode(this->color_mode_)) {
156
+ ESP_LOGW(TAG, "'%s' does not support color mode %s", name, LOG_STR_ARG(color_mode_to_human(this->color_mode_)));
157
+ this->set_flag_(FLAG_HAS_COLOR_MODE, false);
142
158
  }
143
159
 
144
160
  // Ensure there is always a color mode set
145
- if (!this->color_mode_.has_value()) {
161
+ if (!this->has_color_mode()) {
146
162
  this->color_mode_ = this->compute_color_mode_();
163
+ this->set_flag_(FLAG_HAS_COLOR_MODE, true);
147
164
  }
148
- auto color_mode = *this->color_mode_;
165
+ auto color_mode = this->color_mode_;
149
166
 
150
167
  // Transform calls that use non-native parameters for the current mode.
151
168
  this->transform_parameters_();
152
169
 
153
170
  // Brightness exists check
154
- if (this->brightness_.has_value() && *this->brightness_ > 0.0f && !(color_mode & ColorCapability::BRIGHTNESS)) {
155
- ESP_LOGW(TAG, "'%s' - This light does not support setting brightness!", name);
156
- this->brightness_.reset();
171
+ if (this->has_brightness() && this->brightness_ > 0.0f && !(color_mode & ColorCapability::BRIGHTNESS)) {
172
+ ESP_LOGW(TAG, "'%s': setting brightness not supported", name);
173
+ this->set_flag_(FLAG_HAS_BRIGHTNESS, false);
157
174
  }
158
175
 
159
176
  // Transition length possible check
160
- if (this->transition_length_.has_value() && *this->transition_length_ != 0 &&
161
- !(color_mode & ColorCapability::BRIGHTNESS)) {
162
- ESP_LOGW(TAG, "'%s' - This light does not support transitions!", name);
163
- this->transition_length_.reset();
177
+ if (this->has_transition_() && this->transition_length_ != 0 && !(color_mode & ColorCapability::BRIGHTNESS)) {
178
+ ESP_LOGW(TAG, "'%s': transitions not supported", name);
179
+ this->set_flag_(FLAG_HAS_TRANSITION, false);
164
180
  }
165
181
 
166
182
  // Color brightness exists check
167
- if (this->color_brightness_.has_value() && *this->color_brightness_ > 0.0f && !(color_mode & ColorCapability::RGB)) {
168
- ESP_LOGW(TAG, "'%s' - This color mode does not support setting RGB brightness!", name);
169
- this->color_brightness_.reset();
183
+ 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);
185
+ this->set_flag_(FLAG_HAS_COLOR_BRIGHTNESS, false);
170
186
  }
171
187
 
172
188
  // RGB exists check
173
- if ((this->red_.has_value() && *this->red_ > 0.0f) || (this->green_.has_value() && *this->green_ > 0.0f) ||
174
- (this->blue_.has_value() && *this->blue_ > 0.0f)) {
189
+ if ((this->has_red() && this->red_ > 0.0f) || (this->has_green() && this->green_ > 0.0f) ||
190
+ (this->has_blue() && this->blue_ > 0.0f)) {
175
191
  if (!(color_mode & ColorCapability::RGB)) {
176
- ESP_LOGW(TAG, "'%s' - This color mode does not support setting RGB color!", name);
177
- this->red_.reset();
178
- this->green_.reset();
179
- this->blue_.reset();
192
+ ESP_LOGW(TAG, "'%s': color mode does not support setting RGB color", name);
193
+ this->set_flag_(FLAG_HAS_RED, false);
194
+ this->set_flag_(FLAG_HAS_GREEN, false);
195
+ this->set_flag_(FLAG_HAS_BLUE, false);
180
196
  }
181
197
  }
182
198
 
183
199
  // White value exists check
184
- if (this->white_.has_value() && *this->white_ > 0.0f &&
200
+ if (this->has_white() && this->white_ > 0.0f &&
185
201
  !(color_mode & ColorCapability::WHITE || color_mode & ColorCapability::COLD_WARM_WHITE)) {
186
- ESP_LOGW(TAG, "'%s' - This color mode does not support setting white value!", name);
187
- this->white_.reset();
202
+ ESP_LOGW(TAG, "'%s': color mode does not support setting white value", name);
203
+ this->set_flag_(FLAG_HAS_WHITE, false);
188
204
  }
189
205
 
190
206
  // Color temperature exists check
191
- if (this->color_temperature_.has_value() &&
207
+ if (this->has_color_temperature() &&
192
208
  !(color_mode & ColorCapability::COLOR_TEMPERATURE || color_mode & ColorCapability::COLD_WARM_WHITE)) {
193
- ESP_LOGW(TAG, "'%s' - This color mode does not support setting color temperature!", name);
194
- this->color_temperature_.reset();
209
+ ESP_LOGW(TAG, "'%s': color mode does not support setting color temperature", name);
210
+ this->set_flag_(FLAG_HAS_COLOR_TEMPERATURE, false);
195
211
  }
196
212
 
197
213
  // Cold/warm white value exists check
198
- if ((this->cold_white_.has_value() && *this->cold_white_ > 0.0f) ||
199
- (this->warm_white_.has_value() && *this->warm_white_ > 0.0f)) {
214
+ if ((this->has_cold_white() && this->cold_white_ > 0.0f) || (this->has_warm_white() && this->warm_white_ > 0.0f)) {
200
215
  if (!(color_mode & ColorCapability::COLD_WARM_WHITE)) {
201
- ESP_LOGW(TAG, "'%s' - This color mode does not support setting cold/warm white value!", name);
202
- this->cold_white_.reset();
203
- this->warm_white_.reset();
216
+ ESP_LOGW(TAG, "'%s': color mode does not support setting cold/warm white value", name);
217
+ this->set_flag_(FLAG_HAS_COLD_WHITE, false);
218
+ this->set_flag_(FLAG_HAS_WARM_WHITE, false);
204
219
  }
205
220
  }
206
221
 
207
222
  #define VALIDATE_RANGE_(name_, upper_name, min, max) \
208
- if (name_##_.has_value()) { \
209
- auto val = *name_##_; \
223
+ if (this->has_##name_()) { \
224
+ auto val = this->name_##_; \
210
225
  if (val < (min) || val > (max)) { \
211
- ESP_LOGW(TAG, "'%s' - %s value %.2f is out of range [%.1f - %.1f]!", name, LOG_STR_LITERAL(upper_name), val, \
226
+ ESP_LOGW(TAG, "'%s': %s value %.2f is out of range [%.1f - %.1f]", name, LOG_STR_LITERAL(upper_name), val, \
212
227
  (min), (max)); \
213
- name_##_ = clamp(val, (min), (max)); \
228
+ this->name_##_ = clamp(val, (min), (max)); \
214
229
  } \
215
230
  }
216
231
  #define VALIDATE_RANGE(name, upper_name) VALIDATE_RANGE_(name, upper_name, 0.0f, 1.0f)
@@ -227,110 +242,116 @@ LightColorValues LightCall::validate_() {
227
242
  VALIDATE_RANGE_(color_temperature, "Color temperature", traits.get_min_mireds(), traits.get_max_mireds())
228
243
 
229
244
  // Flag whether an explicit turn off was requested, in which case we'll also stop the effect.
230
- bool explicit_turn_off_request = this->state_.has_value() && !*this->state_;
245
+ bool explicit_turn_off_request = this->has_state() && !this->state_;
231
246
 
232
247
  // Turn off when brightness is set to zero, and reset brightness (so that it has nonzero brightness when turned on).
233
- if (this->brightness_.has_value() && *this->brightness_ == 0.0f) {
234
- this->state_ = optional<float>(false);
235
- this->brightness_ = optional<float>(1.0f);
248
+ if (this->has_brightness() && this->brightness_ == 0.0f) {
249
+ this->state_ = false;
250
+ this->set_flag_(FLAG_HAS_STATE, true);
251
+ this->brightness_ = 1.0f;
236
252
  }
237
253
 
238
254
  // Set color brightness to 100% if currently zero and a color is set.
239
- if (this->red_.has_value() || this->green_.has_value() || this->blue_.has_value()) {
240
- if (!this->color_brightness_.has_value() && this->parent_->remote_values.get_color_brightness() == 0.0f)
241
- this->color_brightness_ = optional<float>(1.0f);
255
+ if (this->has_red() || this->has_green() || this->has_blue()) {
256
+ if (!this->has_color_brightness() && this->parent_->remote_values.get_color_brightness() == 0.0f) {
257
+ this->color_brightness_ = 1.0f;
258
+ this->set_flag_(FLAG_HAS_COLOR_BRIGHTNESS, true);
259
+ }
242
260
  }
243
261
 
244
262
  // Create color values for the light with this call applied.
245
263
  auto v = this->parent_->remote_values;
246
- if (this->color_mode_.has_value())
247
- v.set_color_mode(*this->color_mode_);
248
- if (this->state_.has_value())
249
- v.set_state(*this->state_);
250
- if (this->brightness_.has_value())
251
- v.set_brightness(*this->brightness_);
252
- if (this->color_brightness_.has_value())
253
- v.set_color_brightness(*this->color_brightness_);
254
- if (this->red_.has_value())
255
- v.set_red(*this->red_);
256
- if (this->green_.has_value())
257
- v.set_green(*this->green_);
258
- if (this->blue_.has_value())
259
- v.set_blue(*this->blue_);
260
- if (this->white_.has_value())
261
- v.set_white(*this->white_);
262
- if (this->color_temperature_.has_value())
263
- v.set_color_temperature(*this->color_temperature_);
264
- if (this->cold_white_.has_value())
265
- v.set_cold_white(*this->cold_white_);
266
- if (this->warm_white_.has_value())
267
- v.set_warm_white(*this->warm_white_);
264
+ if (this->has_color_mode())
265
+ v.set_color_mode(this->color_mode_);
266
+ if (this->has_state())
267
+ v.set_state(this->state_);
268
+ if (this->has_brightness())
269
+ v.set_brightness(this->brightness_);
270
+ if (this->has_color_brightness())
271
+ v.set_color_brightness(this->color_brightness_);
272
+ if (this->has_red())
273
+ v.set_red(this->red_);
274
+ if (this->has_green())
275
+ v.set_green(this->green_);
276
+ if (this->has_blue())
277
+ v.set_blue(this->blue_);
278
+ if (this->has_white())
279
+ v.set_white(this->white_);
280
+ if (this->has_color_temperature())
281
+ v.set_color_temperature(this->color_temperature_);
282
+ if (this->has_cold_white())
283
+ v.set_cold_white(this->cold_white_);
284
+ if (this->has_warm_white())
285
+ v.set_warm_white(this->warm_white_);
268
286
 
269
287
  v.normalize_color();
270
288
 
271
289
  // Flash length check
272
- if (this->has_flash_() && *this->flash_length_ == 0) {
273
- ESP_LOGW(TAG, "'%s' - Flash length must be greater than zero!", name);
274
- this->flash_length_.reset();
290
+ if (this->has_flash_() && this->flash_length_ == 0) {
291
+ ESP_LOGW(TAG, "'%s': flash length must be greater than zero", name);
292
+ this->set_flag_(FLAG_HAS_FLASH, false);
275
293
  }
276
294
 
277
295
  // validate transition length/flash length/effect not used at the same time
278
296
  bool supports_transition = color_mode & ColorCapability::BRIGHTNESS;
279
297
 
280
298
  // If effect is already active, remove effect start
281
- if (this->has_effect_() && *this->effect_ == this->parent_->active_effect_index_) {
282
- this->effect_.reset();
299
+ if (this->has_effect_() && this->effect_ == this->parent_->active_effect_index_) {
300
+ this->set_flag_(FLAG_HAS_EFFECT, false);
283
301
  }
284
302
 
285
303
  // validate effect index
286
- if (this->has_effect_() && *this->effect_ > this->parent_->effects_.size()) {
287
- ESP_LOGW(TAG, "'%s' - Invalid effect index %" PRIu32 "!", name, *this->effect_);
288
- this->effect_.reset();
304
+ if (this->has_effect_() && this->effect_ > this->parent_->effects_.size()) {
305
+ ESP_LOGW(TAG, "'%s': invalid effect index %" PRIu32, name, this->effect_);
306
+ this->set_flag_(FLAG_HAS_EFFECT, false);
289
307
  }
290
308
 
291
309
  if (this->has_effect_() && (this->has_transition_() || this->has_flash_())) {
292
- ESP_LOGW(TAG, "'%s' - Effect cannot be used together with transition/flash!", name);
293
- this->transition_length_.reset();
294
- this->flash_length_.reset();
310
+ ESP_LOGW(TAG, "'%s': effect cannot be used with transition/flash", name);
311
+ this->set_flag_(FLAG_HAS_TRANSITION, false);
312
+ this->set_flag_(FLAG_HAS_FLASH, false);
295
313
  }
296
314
 
297
315
  if (this->has_flash_() && this->has_transition_()) {
298
- ESP_LOGW(TAG, "'%s' - Flash cannot be used together with transition!", name);
299
- this->transition_length_.reset();
316
+ ESP_LOGW(TAG, "'%s': flash cannot be used with transition", name);
317
+ this->set_flag_(FLAG_HAS_TRANSITION, false);
300
318
  }
301
319
 
302
- if (!this->has_transition_() && !this->has_flash_() && (!this->has_effect_() || *this->effect_ == 0) &&
320
+ if (!this->has_transition_() && !this->has_flash_() && (!this->has_effect_() || this->effect_ == 0) &&
303
321
  supports_transition) {
304
322
  // nothing specified and light supports transitions, set default transition length
305
323
  this->transition_length_ = this->parent_->default_transition_length_;
324
+ this->set_flag_(FLAG_HAS_TRANSITION, true);
306
325
  }
307
326
 
308
- if (this->transition_length_.value_or(0) == 0) {
327
+ if (this->has_transition_() && this->transition_length_ == 0) {
309
328
  // 0 transition is interpreted as no transition (instant change)
310
- this->transition_length_.reset();
329
+ this->set_flag_(FLAG_HAS_TRANSITION, false);
311
330
  }
312
331
 
313
332
  if (this->has_transition_() && !supports_transition) {
314
- ESP_LOGW(TAG, "'%s' - Light does not support transitions!", name);
315
- this->transition_length_.reset();
333
+ ESP_LOGW(TAG, "'%s': transitions not supported", name);
334
+ this->set_flag_(FLAG_HAS_TRANSITION, false);
316
335
  }
317
336
 
318
337
  // If not a flash and turning the light off, then disable the light
319
338
  // Do not use light color values directly, so that effects can set 0% brightness
320
339
  // Reason: When user turns off the light in frontend, the effect should also stop
321
- if (!this->has_flash_() && !this->state_.value_or(v.is_on())) {
340
+ bool target_state = this->has_state() ? this->state_ : v.is_on();
341
+ if (!this->has_flash_() && !target_state) {
322
342
  if (this->has_effect_()) {
323
- ESP_LOGW(TAG, "'%s' - Cannot start an effect when turning off!", name);
324
- this->effect_.reset();
343
+ ESP_LOGW(TAG, "'%s': cannot start effect when turning off", name);
344
+ this->set_flag_(FLAG_HAS_EFFECT, false);
325
345
  } else if (this->parent_->active_effect_index_ != 0 && explicit_turn_off_request) {
326
346
  // Auto turn off effect
327
347
  this->effect_ = 0;
348
+ this->set_flag_(FLAG_HAS_EFFECT, true);
328
349
  }
329
350
  }
330
351
 
331
352
  // Disable saving for flashes
332
353
  if (this->has_flash_())
333
- this->save_ = false;
354
+ this->set_flag_(FLAG_SAVE, false);
334
355
 
335
356
  return v;
336
357
  }
@@ -343,24 +364,27 @@ void LightCall::transform_parameters_() {
343
364
  // - RGBWW lights with color_interlock=true, which also sets "brightness" and
344
365
  // "color_temperature" (without color_interlock, CW/WW are set directly)
345
366
  // - Legacy Home Assistant (pre-colormode), which sets "white" and "color_temperature"
346
- if (((this->white_.has_value() && *this->white_ > 0.0f) || this->color_temperature_.has_value()) && //
347
- (*this->color_mode_ & ColorCapability::COLD_WARM_WHITE) && //
348
- !(*this->color_mode_ & ColorCapability::WHITE) && //
349
- !(*this->color_mode_ & ColorCapability::COLOR_TEMPERATURE) && //
367
+ if (((this->has_white() && this->white_ > 0.0f) || this->has_color_temperature()) && //
368
+ (this->color_mode_ & ColorCapability::COLD_WARM_WHITE) && //
369
+ !(this->color_mode_ & ColorCapability::WHITE) && //
370
+ !(this->color_mode_ & ColorCapability::COLOR_TEMPERATURE) && //
350
371
  traits.get_min_mireds() > 0.0f && traits.get_max_mireds() > 0.0f) {
351
- ESP_LOGD(TAG, "'%s' - Setting cold/warm white channels using white/color temperature values.",
372
+ ESP_LOGD(TAG, "'%s': setting cold/warm white channels using white/color temperature values",
352
373
  this->parent_->get_name().c_str());
353
- if (this->color_temperature_.has_value()) {
354
- const float color_temp = clamp(*this->color_temperature_, traits.get_min_mireds(), traits.get_max_mireds());
374
+ if (this->has_color_temperature()) {
375
+ const float color_temp = clamp(this->color_temperature_, traits.get_min_mireds(), traits.get_max_mireds());
355
376
  const float ww_fraction =
356
377
  (color_temp - traits.get_min_mireds()) / (traits.get_max_mireds() - traits.get_min_mireds());
357
378
  const float cw_fraction = 1.0f - ww_fraction;
358
379
  const float max_cw_ww = std::max(ww_fraction, cw_fraction);
359
380
  this->cold_white_ = gamma_uncorrect(cw_fraction / max_cw_ww, this->parent_->get_gamma_correct());
360
381
  this->warm_white_ = gamma_uncorrect(ww_fraction / max_cw_ww, this->parent_->get_gamma_correct());
382
+ this->set_flag_(FLAG_HAS_COLD_WHITE, true);
383
+ this->set_flag_(FLAG_HAS_WARM_WHITE, true);
361
384
  }
362
- if (this->white_.has_value()) {
363
- this->brightness_ = *this->white_;
385
+ if (this->has_white()) {
386
+ this->brightness_ = this->white_;
387
+ this->set_flag_(FLAG_HAS_BRIGHTNESS, true);
364
388
  }
365
389
  }
366
390
  }
@@ -378,7 +402,7 @@ ColorMode LightCall::compute_color_mode_() {
378
402
 
379
403
  // Don't change if the light is being turned off.
380
404
  ColorMode current_mode = this->parent_->remote_values.get_color_mode();
381
- if (this->state_.has_value() && !*this->state_)
405
+ if (this->has_state() && !this->state_)
382
406
  return current_mode;
383
407
 
384
408
  // If no color mode is specified, we try to guess the color mode. This is needed for backward compatibility to
@@ -388,8 +412,8 @@ ColorMode LightCall::compute_color_mode_() {
388
412
 
389
413
  // Don't change if the current mode is suitable.
390
414
  if (suitable_modes.count(current_mode) > 0) {
391
- ESP_LOGI(TAG, "'%s' - Keeping current color mode %s for call without color mode.",
392
- this->parent_->get_name().c_str(), LOG_STR_ARG(color_mode_to_human(current_mode)));
415
+ ESP_LOGI(TAG, "'%s': color mode not specified; retaining %s", this->parent_->get_name().c_str(),
416
+ LOG_STR_ARG(color_mode_to_human(current_mode)));
393
417
  return current_mode;
394
418
  }
395
419
 
@@ -398,7 +422,7 @@ ColorMode LightCall::compute_color_mode_() {
398
422
  if (supported_modes.count(mode) == 0)
399
423
  continue;
400
424
 
401
- ESP_LOGI(TAG, "'%s' - Using color mode %s for call without color mode.", this->parent_->get_name().c_str(),
425
+ ESP_LOGI(TAG, "'%s': color mode not specified; using %s", this->parent_->get_name().c_str(),
402
426
  LOG_STR_ARG(color_mode_to_human(mode)));
403
427
  return mode;
404
428
  }
@@ -406,17 +430,17 @@ ColorMode LightCall::compute_color_mode_() {
406
430
  // There's no supported mode for this call, so warn, use the current more or a mode at random and let validation strip
407
431
  // out whatever we don't support.
408
432
  auto color_mode = current_mode != ColorMode::UNKNOWN ? current_mode : *supported_modes.begin();
409
- ESP_LOGW(TAG, "'%s' - No color mode suitable for this call supported, defaulting to %s!",
410
- this->parent_->get_name().c_str(), LOG_STR_ARG(color_mode_to_human(color_mode)));
433
+ ESP_LOGW(TAG, "'%s': no suitable color mode supported; defaulting to %s", this->parent_->get_name().c_str(),
434
+ LOG_STR_ARG(color_mode_to_human(color_mode)));
411
435
  return color_mode;
412
436
  }
413
437
  std::set<ColorMode> LightCall::get_suitable_color_modes_() {
414
- bool has_white = this->white_.has_value() && *this->white_ > 0.0f;
415
- bool has_ct = this->color_temperature_.has_value();
416
- bool has_cwww = (this->cold_white_.has_value() && *this->cold_white_ > 0.0f) ||
417
- (this->warm_white_.has_value() && *this->warm_white_ > 0.0f);
418
- bool has_rgb = (this->color_brightness_.has_value() && *this->color_brightness_ > 0.0f) ||
419
- (this->red_.has_value() || this->green_.has_value() || this->blue_.has_value());
438
+ bool has_white = this->has_white() && this->white_ > 0.0f;
439
+ bool has_ct = this->has_color_temperature();
440
+ bool has_cwww =
441
+ (this->has_cold_white() && this->cold_white_ > 0.0f) || (this->has_warm_white() && this->warm_white_ > 0.0f);
442
+ bool has_rgb = (this->has_color_brightness() && this->color_brightness_ > 0.0f) ||
443
+ (this->has_red() || this->has_green() || this->has_blue());
420
444
 
421
445
  #define KEY(white, ct, cwww, rgb) ((white) << 0 | (ct) << 1 | (cwww) << 2 | (rgb) << 3)
422
446
  #define ENTRY(white, ct, cwww, rgb, ...) \
@@ -472,7 +496,7 @@ LightCall &LightCall::set_effect(const std::string &effect) {
472
496
  }
473
497
  }
474
498
  if (!found) {
475
- ESP_LOGW(TAG, "'%s' - No such effect '%s'", this->parent_->get_name().c_str(), effect.c_str());
499
+ ESP_LOGW(TAG, "'%s': no such effect '%s'", this->parent_->get_name().c_str(), effect.c_str());
476
500
  }
477
501
  return *this;
478
502
  }
@@ -491,7 +515,7 @@ LightCall &LightCall::from_light_color_values(const LightColorValues &values) {
491
515
  return *this;
492
516
  }
493
517
  ColorMode LightCall::get_active_color_mode_() {
494
- return this->color_mode_.value_or(this->parent_->remote_values.get_color_mode());
518
+ return this->has_color_mode() ? this->color_mode_ : this->parent_->remote_values.get_color_mode();
495
519
  }
496
520
  LightCall &LightCall::set_transition_length_if_supported(uint32_t transition_length) {
497
521
  if (this->get_active_color_mode_() & ColorCapability::BRIGHTNESS)
@@ -505,7 +529,7 @@ LightCall &LightCall::set_brightness_if_supported(float brightness) {
505
529
  }
506
530
  LightCall &LightCall::set_color_mode_if_supported(ColorMode color_mode) {
507
531
  if (this->parent_->get_traits().supports_color_mode(color_mode))
508
- this->color_mode_ = color_mode;
532
+ this->set_color_mode(color_mode);
509
533
  return *this;
510
534
  }
511
535
  LightCall &LightCall::set_color_brightness_if_supported(float brightness) {
@@ -549,110 +573,19 @@ LightCall &LightCall::set_warm_white_if_supported(float warm_white) {
549
573
  this->set_warm_white(warm_white);
550
574
  return *this;
551
575
  }
552
- LightCall &LightCall::set_state(optional<bool> state) {
553
- this->state_ = state;
554
- return *this;
555
- }
556
- LightCall &LightCall::set_state(bool state) {
557
- this->state_ = state;
558
- return *this;
559
- }
560
- LightCall &LightCall::set_transition_length(optional<uint32_t> transition_length) {
561
- this->transition_length_ = transition_length;
562
- return *this;
563
- }
564
- LightCall &LightCall::set_transition_length(uint32_t transition_length) {
565
- this->transition_length_ = transition_length;
566
- return *this;
567
- }
568
- LightCall &LightCall::set_flash_length(optional<uint32_t> flash_length) {
569
- this->flash_length_ = flash_length;
570
- return *this;
571
- }
572
- LightCall &LightCall::set_flash_length(uint32_t flash_length) {
573
- this->flash_length_ = flash_length;
574
- return *this;
575
- }
576
- LightCall &LightCall::set_brightness(optional<float> brightness) {
577
- this->brightness_ = brightness;
578
- return *this;
579
- }
580
- LightCall &LightCall::set_brightness(float brightness) {
581
- this->brightness_ = brightness;
582
- return *this;
583
- }
584
- LightCall &LightCall::set_color_mode(optional<ColorMode> color_mode) {
585
- this->color_mode_ = color_mode;
586
- return *this;
587
- }
588
- LightCall &LightCall::set_color_mode(ColorMode color_mode) {
589
- this->color_mode_ = color_mode;
590
- return *this;
591
- }
592
- LightCall &LightCall::set_color_brightness(optional<float> brightness) {
593
- this->color_brightness_ = brightness;
594
- return *this;
595
- }
596
- LightCall &LightCall::set_color_brightness(float brightness) {
597
- this->color_brightness_ = brightness;
598
- return *this;
599
- }
600
- LightCall &LightCall::set_red(optional<float> red) {
601
- this->red_ = red;
602
- return *this;
603
- }
604
- LightCall &LightCall::set_red(float red) {
605
- this->red_ = red;
606
- return *this;
607
- }
608
- LightCall &LightCall::set_green(optional<float> green) {
609
- this->green_ = green;
610
- return *this;
611
- }
612
- LightCall &LightCall::set_green(float green) {
613
- this->green_ = green;
614
- return *this;
615
- }
616
- LightCall &LightCall::set_blue(optional<float> blue) {
617
- this->blue_ = blue;
618
- return *this;
619
- }
620
- LightCall &LightCall::set_blue(float blue) {
621
- this->blue_ = blue;
622
- return *this;
623
- }
624
- LightCall &LightCall::set_white(optional<float> white) {
625
- this->white_ = white;
626
- return *this;
627
- }
628
- LightCall &LightCall::set_white(float white) {
629
- this->white_ = white;
630
- return *this;
631
- }
632
- LightCall &LightCall::set_color_temperature(optional<float> color_temperature) {
633
- this->color_temperature_ = color_temperature;
634
- return *this;
635
- }
636
- LightCall &LightCall::set_color_temperature(float color_temperature) {
637
- this->color_temperature_ = color_temperature;
638
- return *this;
639
- }
640
- LightCall &LightCall::set_cold_white(optional<float> cold_white) {
641
- this->cold_white_ = cold_white;
642
- return *this;
643
- }
644
- LightCall &LightCall::set_cold_white(float cold_white) {
645
- this->cold_white_ = cold_white;
646
- return *this;
647
- }
648
- LightCall &LightCall::set_warm_white(optional<float> warm_white) {
649
- this->warm_white_ = warm_white;
650
- return *this;
651
- }
652
- LightCall &LightCall::set_warm_white(float warm_white) {
653
- this->warm_white_ = warm_white;
654
- return *this;
655
- }
576
+ IMPLEMENT_LIGHT_CALL_SETTER(state, bool, FLAG_HAS_STATE)
577
+ IMPLEMENT_LIGHT_CALL_SETTER(transition_length, uint32_t, FLAG_HAS_TRANSITION)
578
+ IMPLEMENT_LIGHT_CALL_SETTER(flash_length, uint32_t, FLAG_HAS_FLASH)
579
+ IMPLEMENT_LIGHT_CALL_SETTER(brightness, float, FLAG_HAS_BRIGHTNESS)
580
+ IMPLEMENT_LIGHT_CALL_SETTER(color_mode, ColorMode, FLAG_HAS_COLOR_MODE)
581
+ IMPLEMENT_LIGHT_CALL_SETTER(color_brightness, float, FLAG_HAS_COLOR_BRIGHTNESS)
582
+ IMPLEMENT_LIGHT_CALL_SETTER(red, float, FLAG_HAS_RED)
583
+ IMPLEMENT_LIGHT_CALL_SETTER(green, float, FLAG_HAS_GREEN)
584
+ IMPLEMENT_LIGHT_CALL_SETTER(blue, float, FLAG_HAS_BLUE)
585
+ IMPLEMENT_LIGHT_CALL_SETTER(white, float, FLAG_HAS_WHITE)
586
+ IMPLEMENT_LIGHT_CALL_SETTER(color_temperature, float, FLAG_HAS_COLOR_TEMPERATURE)
587
+ IMPLEMENT_LIGHT_CALL_SETTER(cold_white, float, FLAG_HAS_COLD_WHITE)
588
+ IMPLEMENT_LIGHT_CALL_SETTER(warm_white, float, FLAG_HAS_WARM_WHITE)
656
589
  LightCall &LightCall::set_effect(optional<std::string> effect) {
657
590
  if (effect.has_value())
658
591
  this->set_effect(*effect);
@@ -660,18 +593,22 @@ LightCall &LightCall::set_effect(optional<std::string> effect) {
660
593
  }
661
594
  LightCall &LightCall::set_effect(uint32_t effect_number) {
662
595
  this->effect_ = effect_number;
596
+ this->set_flag_(FLAG_HAS_EFFECT, true);
663
597
  return *this;
664
598
  }
665
599
  LightCall &LightCall::set_effect(optional<uint32_t> effect_number) {
666
- this->effect_ = effect_number;
600
+ if (effect_number.has_value()) {
601
+ this->effect_ = effect_number.value();
602
+ }
603
+ this->set_flag_(FLAG_HAS_EFFECT, effect_number.has_value());
667
604
  return *this;
668
605
  }
669
606
  LightCall &LightCall::set_publish(bool publish) {
670
- this->publish_ = publish;
607
+ this->set_flag_(FLAG_PUBLISH, publish);
671
608
  return *this;
672
609
  }
673
610
  LightCall &LightCall::set_save(bool save) {
674
- this->save_ = save;
611
+ this->set_flag_(FLAG_SAVE, save);
675
612
  return *this;
676
613
  }
677
614
  LightCall &LightCall::set_rgb(float red, float green, float blue) {