esphome 2025.8.3__py3-none-any.whl → 2025.9.0b1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (345) hide show
  1. esphome/__main__.py +36 -42
  2. esphome/components/absolute_humidity/absolute_humidity.cpp +3 -5
  3. esphome/components/adc/adc_sensor_esp32.cpp +29 -6
  4. esphome/components/ags10/ags10.cpp +3 -18
  5. esphome/components/ags10/ags10.h +2 -12
  6. esphome/components/aht10/aht10.cpp +3 -3
  7. esphome/components/airthings_ble/__init__.py +2 -2
  8. esphome/components/alarm_control_panel/__init__.py +2 -2
  9. esphome/components/am2315c/am2315c.cpp +1 -17
  10. esphome/components/am2315c/am2315c.h +2 -3
  11. esphome/components/api/__init__.py +2 -2
  12. esphome/components/api/api_connection.cpp +34 -23
  13. esphome/components/api/api_connection.h +20 -39
  14. esphome/components/api/api_frame_helper.cpp +25 -25
  15. esphome/components/api/api_frame_helper.h +3 -3
  16. esphome/components/api/api_frame_helper_noise.cpp +75 -40
  17. esphome/components/api/api_frame_helper_noise.h +3 -7
  18. esphome/components/api/api_frame_helper_plaintext.cpp +17 -4
  19. esphome/components/api/api_frame_helper_plaintext.h +1 -4
  20. esphome/components/api/api_pb2.cpp +20 -2
  21. esphome/components/api/api_pb2.h +146 -141
  22. esphome/components/api/api_pb2_dump.cpp +12 -1
  23. esphome/components/api/proto.cpp +33 -37
  24. esphome/components/async_tcp/__init__.py +2 -2
  25. esphome/components/atm90e26/sensor.py +2 -0
  26. esphome/components/atm90e32/sensor.py +4 -2
  27. esphome/components/audio_adc/__init__.py +2 -2
  28. esphome/components/audio_dac/__init__.py +2 -2
  29. esphome/components/axs15231/touchscreen/axs15231_touchscreen.cpp +1 -1
  30. esphome/components/bedjet/bedjet_hub.cpp +1 -1
  31. esphome/components/binary_sensor/__init__.py +2 -2
  32. esphome/components/binary_sensor/binary_sensor.cpp +13 -0
  33. esphome/components/binary_sensor/binary_sensor.h +4 -7
  34. esphome/components/bl0940/__init__.py +6 -1
  35. esphome/components/bl0940/bl0940.cpp +178 -41
  36. esphome/components/bl0940/bl0940.h +121 -76
  37. esphome/components/bl0940/button/__init__.py +27 -0
  38. esphome/components/bl0940/button/calibration_reset_button.cpp +20 -0
  39. esphome/components/bl0940/button/calibration_reset_button.h +19 -0
  40. esphome/components/bl0940/number/__init__.py +94 -0
  41. esphome/components/bl0940/number/calibration_number.cpp +29 -0
  42. esphome/components/bl0940/number/calibration_number.h +26 -0
  43. esphome/components/bl0940/sensor.py +151 -2
  44. esphome/components/bl0942/bl0942.cpp +1 -1
  45. esphome/components/ble_client/output/__init__.py +4 -4
  46. esphome/components/bluetooth_proxy/__init__.py +1 -1
  47. esphome/components/bluetooth_proxy/bluetooth_connection.h +1 -1
  48. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +15 -7
  49. esphome/components/bluetooth_proxy/bluetooth_proxy.h +3 -2
  50. esphome/components/button/__init__.py +2 -2
  51. esphome/components/button/button.cpp +13 -0
  52. esphome/components/button/button.h +4 -7
  53. esphome/components/camera/buffer.h +18 -0
  54. esphome/components/camera/buffer_impl.cpp +20 -0
  55. esphome/components/camera/buffer_impl.h +26 -0
  56. esphome/components/camera/camera.h +43 -0
  57. esphome/components/camera/encoder.h +69 -0
  58. esphome/components/camera_encoder/__init__.py +62 -0
  59. esphome/components/camera_encoder/encoder_buffer_impl.cpp +23 -0
  60. esphome/components/camera_encoder/encoder_buffer_impl.h +25 -0
  61. esphome/components/camera_encoder/esp32_camera_jpeg_encoder.cpp +82 -0
  62. esphome/components/camera_encoder/esp32_camera_jpeg_encoder.h +39 -0
  63. esphome/components/captive_portal/__init__.py +2 -2
  64. esphome/components/captive_portal/captive_portal.cpp +35 -12
  65. esphome/components/captive_portal/captive_portal.h +3 -3
  66. esphome/components/ccs811/ccs811.cpp +3 -3
  67. esphome/components/climate/__init__.py +2 -2
  68. esphome/components/climate/climate.cpp +1 -1
  69. esphome/components/cover/__init__.py +5 -5
  70. esphome/components/cover/cover.cpp +1 -1
  71. esphome/components/cover/cover.h +2 -2
  72. esphome/components/dallas_temp/dallas_temp.cpp +2 -2
  73. esphome/components/datetime/__init__.py +2 -2
  74. esphome/components/datetime/date_entity.h +2 -2
  75. esphome/components/datetime/datetime_entity.h +2 -2
  76. esphome/components/datetime/time_entity.h +2 -2
  77. esphome/components/debug/debug_esp32.cpp +1 -1
  78. esphome/components/display/__init__.py +4 -4
  79. esphome/components/duty_time/duty_time_sensor.cpp +1 -1
  80. esphome/components/esp32/__init__.py +0 -5
  81. esphome/components/esp32/gpio.cpp +27 -23
  82. esphome/components/esp32/gpio.h +26 -11
  83. esphome/components/esp32/preferences.cpp +8 -4
  84. esphome/components/esp32_ble/__init__.py +7 -2
  85. esphome/components/esp32_ble_client/ble_client_base.cpp +7 -3
  86. esphome/components/esp32_ble_tracker/__init__.py +2 -2
  87. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +9 -44
  88. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +2 -14
  89. esphome/components/esp8266/__init__.py +2 -2
  90. esphome/components/esp8266/core.cpp +2 -2
  91. esphome/components/esp8266/gpio.py +4 -4
  92. esphome/components/esp8266/preferences.cpp +30 -28
  93. esphome/components/esphome/ota/__init__.py +2 -2
  94. esphome/components/esphome/ota/ota_esphome.cpp +21 -19
  95. esphome/components/esphome/ota/ota_esphome.h +6 -5
  96. esphome/components/ethernet/__init__.py +7 -2
  97. esphome/components/ethernet/ethernet_component.cpp +1 -1
  98. esphome/components/event/__init__.py +2 -2
  99. esphome/components/event/event.h +4 -4
  100. esphome/components/fan/__init__.py +2 -2
  101. esphome/components/fan/fan.cpp +2 -1
  102. esphome/components/gdk101/gdk101.cpp +4 -4
  103. esphome/components/globals/__init__.py +2 -2
  104. esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp +19 -18
  105. esphome/components/gpio_expander/cached_gpio.h +36 -16
  106. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.cpp +5 -5
  107. esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +1 -1
  108. esphome/components/haier/haier_base.cpp +1 -1
  109. esphome/components/haier/hon_climate.cpp +1 -1
  110. esphome/components/hlw8012/hlw8012.cpp +5 -5
  111. esphome/components/honeywellabp2_i2c/honeywellabp2.cpp +4 -4
  112. esphome/components/host/preferences.h +3 -2
  113. esphome/components/hte501/hte501.cpp +3 -21
  114. esphome/components/hte501/hte501.h +2 -3
  115. esphome/components/http_request/ota/__init__.py +2 -2
  116. esphome/components/i2c/__init__.py +2 -2
  117. esphome/components/i2c/i2c.cpp +13 -9
  118. esphome/components/i2c/i2c_bus.h +36 -6
  119. esphome/components/i2s_audio/__init__.py +8 -2
  120. esphome/components/i2s_audio/media_player/__init__.py +1 -1
  121. esphome/components/i2s_audio/microphone/__init__.py +1 -1
  122. esphome/components/i2s_audio/speaker/__init__.py +1 -1
  123. esphome/components/inkplate/__init__.py +1 -0
  124. esphome/components/inkplate/const.py +105 -0
  125. esphome/components/inkplate/display.py +238 -0
  126. esphome/components/{inkplate6 → inkplate}/inkplate.cpp +156 -74
  127. esphome/components/{inkplate6 → inkplate}/inkplate.h +28 -68
  128. esphome/components/inkplate6/__init__.py +0 -1
  129. esphome/components/inkplate6/display.py +2 -211
  130. esphome/components/integration/integration_sensor.cpp +1 -1
  131. esphome/components/json/__init__.py +2 -2
  132. esphome/components/kmeteriso/kmeteriso.cpp +1 -1
  133. esphome/components/lc709203f/lc709203f.cpp +4 -17
  134. esphome/components/lc709203f/lc709203f.h +2 -3
  135. esphome/components/ld2420/text_sensor/{text_sensor.cpp → ld2420_text_sensor.cpp} +1 -1
  136. esphome/components/ld2450/ld2450.cpp +1 -1
  137. esphome/components/libretiny/preferences.cpp +13 -5
  138. esphome/components/light/__init__.py +2 -2
  139. esphome/components/light/addressable_light_effect.h +7 -0
  140. esphome/components/light/base_light_effects.h +8 -0
  141. esphome/components/light/light_call.cpp +22 -20
  142. esphome/components/light/light_effect.cpp +36 -0
  143. esphome/components/light/light_effect.h +14 -0
  144. esphome/components/light/light_json_schema.cpp +9 -1
  145. esphome/components/light/light_state.cpp +2 -2
  146. esphome/components/light/light_state.h +39 -0
  147. esphome/components/lock/__init__.py +2 -2
  148. esphome/components/lock/lock.h +2 -2
  149. esphome/components/logger/__init__.py +2 -2
  150. esphome/components/logger/logger.cpp +25 -4
  151. esphome/components/logger/logger.h +1 -1
  152. esphome/components/logger/logger_esp32.cpp +16 -8
  153. esphome/components/logger/logger_esp8266.cpp +11 -3
  154. esphome/components/logger/logger_libretiny.cpp +13 -3
  155. esphome/components/logger/logger_rp2040.cpp +14 -3
  156. esphome/components/logger/logger_zephyr.cpp +15 -4
  157. esphome/components/lvgl/defines.py +1 -0
  158. esphome/components/lvgl/hello_world.py +96 -33
  159. esphome/components/lvgl/number/lvgl_number.h +1 -1
  160. esphome/components/lvgl/select/lvgl_select.h +1 -1
  161. esphome/components/lvgl/widgets/__init__.py +0 -1
  162. esphome/components/lvgl/widgets/spinbox.py +20 -11
  163. esphome/components/m5stack_8angle/binary_sensor/m5stack_8angle_binary_sensor.cpp +1 -1
  164. esphome/components/m5stack_8angle/sensor/m5stack_8angle_sensor.cpp +1 -1
  165. esphome/components/mapping/__init__.py +13 -5
  166. esphome/components/mapping/mapping.h +69 -0
  167. esphome/components/max17043/max17043.cpp +2 -2
  168. esphome/components/mcp23016/__init__.py +1 -0
  169. esphome/components/mcp23016/mcp23016.cpp +20 -5
  170. esphome/components/mcp23016/mcp23016.h +10 -4
  171. esphome/components/mcp23x08_base/mcp23x08_base.cpp +1 -1
  172. esphome/components/mcp23x17_base/mcp23x17_base.cpp +2 -2
  173. esphome/components/mdns/__init__.py +2 -2
  174. esphome/components/mdns/mdns_component.cpp +145 -54
  175. esphome/components/media_player/__init__.py +2 -2
  176. esphome/components/micro_wake_word/__init__.py +2 -2
  177. esphome/components/microphone/__init__.py +2 -2
  178. esphome/components/mipi/__init__.py +77 -33
  179. esphome/components/mipi_rgb/__init__.py +2 -0
  180. esphome/components/mipi_rgb/display.py +321 -0
  181. esphome/components/mipi_rgb/mipi_rgb.cpp +388 -0
  182. esphome/components/mipi_rgb/mipi_rgb.h +127 -0
  183. esphome/components/mipi_rgb/models/guition.py +24 -0
  184. esphome/components/mipi_rgb/models/lilygo.py +228 -0
  185. esphome/components/mipi_rgb/models/rpi.py +9 -0
  186. esphome/components/mipi_rgb/models/st7701s.py +214 -0
  187. esphome/components/mipi_rgb/models/waveshare.py +64 -0
  188. esphome/components/mipi_spi/models/jc.py +229 -0
  189. esphome/components/mlx90614/mlx90614.cpp +1 -16
  190. esphome/components/mlx90614/mlx90614.h +0 -1
  191. esphome/components/mqtt/__init__.py +2 -2
  192. esphome/components/mqtt/mqtt_sensor.cpp +7 -2
  193. esphome/components/ms5611/ms5611.cpp +7 -6
  194. esphome/components/network/__init__.py +2 -2
  195. esphome/components/nextion/nextion_upload.cpp +4 -1
  196. esphome/components/nrf52/__init__.py +49 -6
  197. esphome/components/nrf52/const.py +1 -0
  198. esphome/components/nrf52/dfu.cpp +51 -0
  199. esphome/components/nrf52/dfu.h +24 -0
  200. esphome/components/ntc/ntc.cpp +1 -1
  201. esphome/components/number/__init__.py +2 -2
  202. esphome/components/number/automation.cpp +1 -1
  203. esphome/components/number/number.cpp +21 -0
  204. esphome/components/number/number.h +4 -13
  205. esphome/components/opentherm/hub.h +6 -6
  206. esphome/components/opentherm/number/{number.cpp → opentherm_number.cpp} +2 -2
  207. esphome/components/opentherm/output/{output.cpp → opentherm_output.cpp} +1 -1
  208. esphome/components/opentherm/switch/{switch.cpp → opentherm_switch.cpp} +1 -1
  209. esphome/components/ota/__init__.py +2 -2
  210. esphome/components/pca6416a/__init__.py +1 -0
  211. esphome/components/pca6416a/pca6416a.cpp +20 -5
  212. esphome/components/pca6416a/pca6416a.h +12 -5
  213. esphome/components/pca9554/__init__.py +2 -1
  214. esphome/components/pca9554/pca9554.cpp +12 -18
  215. esphome/components/pca9554/pca9554.h +10 -9
  216. esphome/components/pcf8574/__init__.py +1 -0
  217. esphome/components/pcf8574/pcf8574.cpp +14 -5
  218. esphome/components/pcf8574/pcf8574.h +13 -6
  219. esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +7 -7
  220. esphome/components/pipsolar/__init__.py +3 -3
  221. esphome/components/pipsolar/output/__init__.py +4 -4
  222. esphome/components/pulse_width/pulse_width.cpp +2 -2
  223. esphome/components/qmp6988/qmp6988.cpp +81 -126
  224. esphome/components/qmp6988/qmp6988.h +31 -37
  225. esphome/components/radon_eye_ble/__init__.py +2 -2
  226. esphome/components/remote_base/__init__.py +6 -8
  227. esphome/components/rotary_encoder/rotary_encoder.cpp +1 -1
  228. esphome/components/rp2040/__init__.py +2 -2
  229. esphome/components/runtime_stats/runtime_stats.cpp +10 -23
  230. esphome/components/runtime_stats/runtime_stats.h +4 -10
  231. esphome/components/safe_mode/__init__.py +2 -2
  232. esphome/components/safe_mode/safe_mode.cpp +33 -31
  233. esphome/components/script/script.cpp +6 -0
  234. esphome/components/script/script.h +19 -5
  235. esphome/components/sdm_meter/sensor.py +3 -1
  236. esphome/components/select/__init__.py +2 -2
  237. esphome/components/select/select.h +2 -2
  238. esphome/components/sen5x/sen5x.cpp +58 -55
  239. esphome/components/sen5x/sen5x.h +21 -15
  240. esphome/components/sen5x/sensor.py +67 -44
  241. esphome/components/sensirion_common/i2c_sensirion.cpp +18 -47
  242. esphome/components/sensirion_common/i2c_sensirion.h +39 -55
  243. esphome/components/sensor/__init__.py +2 -2
  244. esphome/components/sensor/automation.h +1 -1
  245. esphome/components/sensor/sensor.cpp +34 -6
  246. esphome/components/sensor/sensor.h +4 -21
  247. esphome/components/sgp30/sgp30.cpp +34 -35
  248. esphome/components/sgp30/sgp30.h +11 -10
  249. esphome/components/sgp4x/sgp4x.cpp +2 -2
  250. esphome/components/shelly_dimmer/light.py +7 -7
  251. esphome/components/sht4x/sht4x.cpp +1 -1
  252. esphome/components/sntp/sntp_component.cpp +36 -9
  253. esphome/components/sntp/sntp_component.h +7 -0
  254. esphome/components/sound_level/sound_level.cpp +1 -1
  255. esphome/components/speaker/__init__.py +2 -2
  256. esphome/components/speaker/media_player/__init__.py +2 -2
  257. esphome/components/speaker/media_player/speaker_media_player.cpp +1 -1
  258. esphome/components/spi/__init__.py +2 -2
  259. esphome/components/sprinkler/sprinkler.cpp +1 -1
  260. esphome/components/sps30/sps30.cpp +18 -23
  261. esphome/components/sps30/sps30.h +3 -3
  262. esphome/components/status_led/__init__.py +2 -2
  263. esphome/components/stepper/__init__.py +2 -2
  264. esphome/components/switch/__init__.py +2 -2
  265. esphome/components/switch/switch.cpp +5 -5
  266. esphome/components/sx1509/__init__.py +1 -1
  267. esphome/components/sx1509/sx1509.cpp +12 -7
  268. esphome/components/sx1509/sx1509.h +11 -4
  269. esphome/components/tca9555/tca9555.cpp +5 -5
  270. esphome/components/tee501/tee501.cpp +2 -21
  271. esphome/components/tee501/tee501.h +2 -4
  272. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +1 -1
  273. esphome/components/template/datetime/template_date.cpp +1 -1
  274. esphome/components/template/datetime/template_datetime.cpp +2 -2
  275. esphome/components/template/datetime/template_time.cpp +1 -1
  276. esphome/components/template/number/template_number.cpp +1 -1
  277. esphome/components/template/select/template_select.cpp +1 -1
  278. esphome/components/template/text/template_text.cpp +1 -1
  279. esphome/components/text/__init__.py +2 -2
  280. esphome/components/text/text.h +2 -2
  281. esphome/components/text_sensor/__init__.py +2 -2
  282. esphome/components/text_sensor/text_sensor.h +4 -4
  283. esphome/components/thermostat/climate.py +11 -7
  284. esphome/components/thermostat/thermostat_climate.cpp +237 -206
  285. esphome/components/thermostat/thermostat_climate.h +52 -41
  286. esphome/components/time/__init__.py +2 -2
  287. esphome/components/tmp1075/tmp1075.cpp +1 -1
  288. esphome/components/total_daily_energy/total_daily_energy.cpp +1 -1
  289. esphome/components/touchscreen/__init__.py +2 -2
  290. esphome/components/tuya/number/tuya_number.cpp +1 -1
  291. esphome/components/udp/udp_component.cpp +3 -3
  292. esphome/components/ufire_ec/ufire_ec.cpp +4 -4
  293. esphome/components/ufire_ise/ufire_ise.cpp +4 -4
  294. esphome/components/update/__init__.py +2 -2
  295. esphome/components/usb_uart/usb_uart.cpp +1 -1
  296. esphome/components/valve/__init__.py +5 -5
  297. esphome/components/valve/valve.cpp +1 -1
  298. esphome/components/valve/valve.h +2 -2
  299. esphome/components/wake_on_lan/wake_on_lan.cpp +2 -2
  300. esphome/components/waveshare_epaper/waveshare_213v3.cpp +1 -1
  301. esphome/components/web_server/__init__.py +2 -2
  302. esphome/components/web_server/ota/__init__.py +2 -2
  303. esphome/components/web_server/ota/ota_web_server.cpp +11 -0
  304. esphome/components/web_server/web_server.cpp +58 -12
  305. esphome/components/web_server_base/__init__.py +2 -2
  306. esphome/components/wifi/__init__.py +5 -5
  307. esphome/components/wifi/wifi_component.cpp +3 -3
  308. esphome/components/wifi/wifi_component_esp_idf.cpp +2 -0
  309. esphome/config_validation.py +2 -2
  310. esphome/const.py +2 -1
  311. esphome/core/__init__.py +1 -0
  312. esphome/core/application.cpp +89 -51
  313. esphome/core/application.h +1 -0
  314. esphome/core/component.cpp +41 -19
  315. esphome/core/component.h +17 -13
  316. esphome/core/config.py +7 -7
  317. esphome/core/defines.h +4 -0
  318. esphome/core/entity_base.cpp +22 -8
  319. esphome/core/entity_base.h +43 -0
  320. esphome/core/helpers.cpp +26 -13
  321. esphome/core/helpers.h +4 -3
  322. esphome/core/ring_buffer.cpp +6 -2
  323. esphome/core/ring_buffer.h +2 -1
  324. esphome/core/scheduler.cpp +175 -94
  325. esphome/core/scheduler.h +66 -35
  326. esphome/core/time.cpp +6 -20
  327. esphome/coroutine.py +80 -3
  328. esphome/cpp_generator.py +13 -0
  329. esphome/cpp_helpers.py +2 -2
  330. esphome/dashboard/web_server.py +67 -10
  331. esphome/espota2.py +13 -6
  332. esphome/helpers.py +68 -83
  333. esphome/resolver.py +67 -0
  334. esphome/util.py +9 -6
  335. esphome/wizard.py +39 -26
  336. {esphome-2025.8.3.dist-info → esphome-2025.9.0b1.dist-info}/METADATA +9 -9
  337. {esphome-2025.8.3.dist-info → esphome-2025.9.0b1.dist-info}/RECORD +345 -314
  338. /esphome/components/ld2420/text_sensor/{text_sensor.h → ld2420_text_sensor.h} +0 -0
  339. /esphome/components/opentherm/number/{number.h → opentherm_number.h} +0 -0
  340. /esphome/components/opentherm/output/{output.h → opentherm_output.h} +0 -0
  341. /esphome/components/opentherm/switch/{switch.h → opentherm_switch.h} +0 -0
  342. {esphome-2025.8.3.dist-info → esphome-2025.9.0b1.dist-info}/WHEEL +0 -0
  343. {esphome-2025.8.3.dist-info → esphome-2025.9.0b1.dist-info}/entry_points.txt +0 -0
  344. {esphome-2025.8.3.dist-info → esphome-2025.9.0b1.dist-info}/licenses/LICENSE +0 -0
  345. {esphome-2025.8.3.dist-info → esphome-2025.9.0b1.dist-info}/top_level.txt +0 -0
@@ -1110,7 +1110,17 @@ void HomeAssistantStateResponse::dump_to(std::string &out) const {
1110
1110
  }
1111
1111
  #endif
1112
1112
  void GetTimeRequest::dump_to(std::string &out) const { out.append("GetTimeRequest {}"); }
1113
- void GetTimeResponse::dump_to(std::string &out) const { dump_field(out, "epoch_seconds", this->epoch_seconds); }
1113
+ void GetTimeResponse::dump_to(std::string &out) const {
1114
+ MessageDumpHelper helper(out, "GetTimeResponse");
1115
+ dump_field(out, "epoch_seconds", this->epoch_seconds);
1116
+ out.append(" timezone: ");
1117
+ if (!this->timezone_ref_.empty()) {
1118
+ out.append("'").append(this->timezone_ref_.c_str()).append("'");
1119
+ } else {
1120
+ out.append("'").append(this->timezone).append("'");
1121
+ }
1122
+ out.append("\n");
1123
+ }
1114
1124
  #ifdef USE_API_SERVICES
1115
1125
  void ListEntitiesServicesArgument::dump_to(std::string &out) const {
1116
1126
  MessageDumpHelper helper(out, "ListEntitiesServicesArgument");
@@ -1704,6 +1714,7 @@ void BluetoothScannerStateResponse::dump_to(std::string &out) const {
1704
1714
  MessageDumpHelper helper(out, "BluetoothScannerStateResponse");
1705
1715
  dump_field(out, "state", static_cast<enums::BluetoothScannerState>(this->state));
1706
1716
  dump_field(out, "mode", static_cast<enums::BluetoothScannerMode>(this->mode));
1717
+ dump_field(out, "configured_mode", static_cast<enums::BluetoothScannerMode>(this->configured_mode));
1707
1718
  }
1708
1719
  void BluetoothScannerSetModeRequest::dump_to(std::string &out) const {
1709
1720
  MessageDumpHelper helper(out, "BluetoothScannerSetModeRequest");
@@ -8,74 +8,70 @@ namespace esphome::api {
8
8
  static const char *const TAG = "api.proto";
9
9
 
10
10
  void ProtoDecodableMessage::decode(const uint8_t *buffer, size_t length) {
11
- uint32_t i = 0;
12
- bool error = false;
13
- while (i < length) {
11
+ const uint8_t *ptr = buffer;
12
+ const uint8_t *end = buffer + length;
13
+
14
+ while (ptr < end) {
14
15
  uint32_t consumed;
15
- auto res = ProtoVarInt::parse(&buffer[i], length - i, &consumed);
16
+
17
+ // Parse field header
18
+ auto res = ProtoVarInt::parse(ptr, end - ptr, &consumed);
16
19
  if (!res.has_value()) {
17
- ESP_LOGV(TAG, "Invalid field start at %" PRIu32, i);
18
- break;
20
+ ESP_LOGV(TAG, "Invalid field start at offset %ld", (long) (ptr - buffer));
21
+ return;
19
22
  }
20
23
 
21
- uint32_t field_type = (res->as_uint32()) & 0b111;
22
- uint32_t field_id = (res->as_uint32()) >> 3;
23
- i += consumed;
24
+ uint32_t tag = res->as_uint32();
25
+ uint32_t field_type = tag & 0b111;
26
+ uint32_t field_id = tag >> 3;
27
+ ptr += consumed;
24
28
 
25
29
  switch (field_type) {
26
30
  case 0: { // VarInt
27
- res = ProtoVarInt::parse(&buffer[i], length - i, &consumed);
31
+ res = ProtoVarInt::parse(ptr, end - ptr, &consumed);
28
32
  if (!res.has_value()) {
29
- ESP_LOGV(TAG, "Invalid VarInt at %" PRIu32, i);
30
- error = true;
31
- break;
33
+ ESP_LOGV(TAG, "Invalid VarInt at offset %ld", (long) (ptr - buffer));
34
+ return;
32
35
  }
33
36
  if (!this->decode_varint(field_id, *res)) {
34
37
  ESP_LOGV(TAG, "Cannot decode VarInt field %" PRIu32 " with value %" PRIu32 "!", field_id, res->as_uint32());
35
38
  }
36
- i += consumed;
39
+ ptr += consumed;
37
40
  break;
38
41
  }
39
42
  case 2: { // Length-delimited
40
- res = ProtoVarInt::parse(&buffer[i], length - i, &consumed);
43
+ res = ProtoVarInt::parse(ptr, end - ptr, &consumed);
41
44
  if (!res.has_value()) {
42
- ESP_LOGV(TAG, "Invalid Length Delimited at %" PRIu32, i);
43
- error = true;
44
- break;
45
+ ESP_LOGV(TAG, "Invalid Length Delimited at offset %ld", (long) (ptr - buffer));
46
+ return;
45
47
  }
46
48
  uint32_t field_length = res->as_uint32();
47
- i += consumed;
48
- if (field_length > length - i) {
49
- ESP_LOGV(TAG, "Out-of-bounds Length Delimited at %" PRIu32, i);
50
- error = true;
51
- break;
49
+ ptr += consumed;
50
+ if (ptr + field_length > end) {
51
+ ESP_LOGV(TAG, "Out-of-bounds Length Delimited at offset %ld", (long) (ptr - buffer));
52
+ return;
52
53
  }
53
- if (!this->decode_length(field_id, ProtoLengthDelimited(&buffer[i], field_length))) {
54
+ if (!this->decode_length(field_id, ProtoLengthDelimited(ptr, field_length))) {
54
55
  ESP_LOGV(TAG, "Cannot decode Length Delimited field %" PRIu32 "!", field_id);
55
56
  }
56
- i += field_length;
57
+ ptr += field_length;
57
58
  break;
58
59
  }
59
60
  case 5: { // 32-bit
60
- if (length - i < 4) {
61
- ESP_LOGV(TAG, "Out-of-bounds Fixed32-bit at %" PRIu32, i);
62
- error = true;
63
- break;
61
+ if (ptr + 4 > end) {
62
+ ESP_LOGV(TAG, "Out-of-bounds Fixed32-bit at offset %ld", (long) (ptr - buffer));
63
+ return;
64
64
  }
65
- uint32_t val = encode_uint32(buffer[i + 3], buffer[i + 2], buffer[i + 1], buffer[i]);
65
+ uint32_t val = encode_uint32(ptr[3], ptr[2], ptr[1], ptr[0]);
66
66
  if (!this->decode_32bit(field_id, Proto32Bit(val))) {
67
67
  ESP_LOGV(TAG, "Cannot decode 32-bit field %" PRIu32 " with value %" PRIu32 "!", field_id, val);
68
68
  }
69
- i += 4;
69
+ ptr += 4;
70
70
  break;
71
71
  }
72
72
  default:
73
- ESP_LOGV(TAG, "Invalid field type at %" PRIu32, i);
74
- error = true;
75
- break;
76
- }
77
- if (error) {
78
- break;
73
+ ESP_LOGV(TAG, "Invalid field type %u at offset %ld", field_type, (long) (ptr - buffer));
74
+ return;
79
75
  }
80
76
  }
81
77
  }
@@ -8,7 +8,7 @@ from esphome.const import (
8
8
  PLATFORM_LN882X,
9
9
  PLATFORM_RTL87XX,
10
10
  )
11
- from esphome.core import CORE, coroutine_with_priority
11
+ from esphome.core import CORE, CoroPriority, coroutine_with_priority
12
12
 
13
13
  CODEOWNERS = ["@esphome/core"]
14
14
 
@@ -27,7 +27,7 @@ CONFIG_SCHEMA = cv.All(
27
27
  )
28
28
 
29
29
 
30
- @coroutine_with_priority(200.0)
30
+ @coroutine_with_priority(CoroPriority.NETWORK_TRANSPORT)
31
31
  async def to_code(config):
32
32
  if CORE.is_esp32 or CORE.is_libretiny:
33
33
  # https://github.com/ESP32Async/AsyncTCP
@@ -16,6 +16,7 @@ from esphome.const import (
16
16
  DEVICE_CLASS_ENERGY,
17
17
  DEVICE_CLASS_POWER,
18
18
  DEVICE_CLASS_POWER_FACTOR,
19
+ DEVICE_CLASS_REACTIVE_POWER,
19
20
  DEVICE_CLASS_VOLTAGE,
20
21
  ICON_CURRENT_AC,
21
22
  ICON_LIGHTBULB,
@@ -78,6 +79,7 @@ CONFIG_SCHEMA = (
78
79
  unit_of_measurement=UNIT_VOLT_AMPS_REACTIVE,
79
80
  icon=ICON_LIGHTBULB,
80
81
  accuracy_decimals=2,
82
+ device_class=DEVICE_CLASS_REACTIVE_POWER,
81
83
  state_class=STATE_CLASS_MEASUREMENT,
82
84
  ),
83
85
  cv.Optional(CONF_POWER_FACTOR): sensor.sensor_schema(
@@ -17,10 +17,12 @@ from esphome.const import (
17
17
  CONF_REACTIVE_POWER,
18
18
  CONF_REVERSE_ACTIVE_ENERGY,
19
19
  CONF_VOLTAGE,
20
+ DEVICE_CLASS_APPARENT_POWER,
20
21
  DEVICE_CLASS_CURRENT,
21
22
  DEVICE_CLASS_ENERGY,
22
23
  DEVICE_CLASS_POWER,
23
24
  DEVICE_CLASS_POWER_FACTOR,
25
+ DEVICE_CLASS_REACTIVE_POWER,
24
26
  DEVICE_CLASS_TEMPERATURE,
25
27
  DEVICE_CLASS_VOLTAGE,
26
28
  ENTITY_CATEGORY_DIAGNOSTIC,
@@ -100,13 +102,13 @@ ATM90E32_PHASE_SCHEMA = cv.Schema(
100
102
  unit_of_measurement=UNIT_VOLT_AMPS_REACTIVE,
101
103
  icon=ICON_LIGHTBULB,
102
104
  accuracy_decimals=2,
103
- device_class=DEVICE_CLASS_POWER,
105
+ device_class=DEVICE_CLASS_REACTIVE_POWER,
104
106
  state_class=STATE_CLASS_MEASUREMENT,
105
107
  ),
106
108
  cv.Optional(CONF_APPARENT_POWER): sensor.sensor_schema(
107
109
  unit_of_measurement=UNIT_VOLT_AMPS,
108
110
  accuracy_decimals=2,
109
- device_class=DEVICE_CLASS_POWER,
111
+ device_class=DEVICE_CLASS_APPARENT_POWER,
110
112
  state_class=STATE_CLASS_MEASUREMENT,
111
113
  ),
112
114
  cv.Optional(CONF_POWER_FACTOR): sensor.sensor_schema(
@@ -2,7 +2,7 @@ from esphome import automation
2
2
  import esphome.codegen as cg
3
3
  import esphome.config_validation as cv
4
4
  from esphome.const import CONF_ID, CONF_MIC_GAIN
5
- from esphome.core import coroutine_with_priority
5
+ from esphome.core import CoroPriority, coroutine_with_priority
6
6
 
7
7
  CODEOWNERS = ["@kbx81"]
8
8
  IS_PLATFORM_COMPONENT = True
@@ -35,7 +35,7 @@ async def audio_adc_set_mic_gain_to_code(config, action_id, template_arg, args):
35
35
  return var
36
36
 
37
37
 
38
- @coroutine_with_priority(100.0)
38
+ @coroutine_with_priority(CoroPriority.CORE)
39
39
  async def to_code(config):
40
40
  cg.add_define("USE_AUDIO_ADC")
41
41
  cg.add_global(audio_adc_ns.using)
@@ -3,7 +3,7 @@ from esphome.automation import maybe_simple_id
3
3
  import esphome.codegen as cg
4
4
  import esphome.config_validation as cv
5
5
  from esphome.const import CONF_ID, CONF_VOLUME
6
- from esphome.core import coroutine_with_priority
6
+ from esphome.core import CoroPriority, coroutine_with_priority
7
7
 
8
8
  CODEOWNERS = ["@kbx81"]
9
9
  IS_PLATFORM_COMPONENT = True
@@ -51,7 +51,7 @@ async def audio_dac_set_volume_to_code(config, action_id, template_arg, args):
51
51
  return var
52
52
 
53
53
 
54
- @coroutine_with_priority(100.0)
54
+ @coroutine_with_priority(CoroPriority.CORE)
55
55
  async def to_code(config):
56
56
  cg.add_define("USE_AUDIO_DAC")
57
57
  cg.add_global(audio_dac_ns.using)
@@ -12,7 +12,7 @@ constexpr static const uint8_t AXS_READ_TOUCHPAD[11] = {0xb5, 0xab, 0xa5, 0x5a,
12
12
 
13
13
  #define ERROR_CHECK(err) \
14
14
  if ((err) != i2c::ERROR_OK) { \
15
- this->status_set_warning("Failed to communicate"); \
15
+ this->status_set_warning(LOG_STR("Failed to communicate")); \
16
16
  return; \
17
17
  }
18
18
 
@@ -493,7 +493,7 @@ void BedJetHub::dump_config() {
493
493
  " ble_client.app_id: %d\n"
494
494
  " ble_client.conn_id: %d",
495
495
  this->get_name().c_str(), this->parent()->app_id, this->parent()->get_conn_id());
496
- LOG_UPDATE_INTERVAL(this)
496
+ LOG_UPDATE_INTERVAL(this);
497
497
  ESP_LOGCONFIG(TAG, " Child components (%d):", this->children_.size());
498
498
  for (auto *child : this->children_) {
499
499
  ESP_LOGCONFIG(TAG, " - %s", child->describe().c_str());
@@ -59,7 +59,7 @@ from esphome.const import (
59
59
  DEVICE_CLASS_VIBRATION,
60
60
  DEVICE_CLASS_WINDOW,
61
61
  )
62
- from esphome.core import CORE, coroutine_with_priority
62
+ from esphome.core import CORE, CoroPriority, coroutine_with_priority
63
63
  from esphome.core.entity_helpers import entity_duplicate_validator, setup_entity
64
64
  from esphome.cpp_generator import MockObjClass
65
65
  from esphome.util import Registry
@@ -652,7 +652,7 @@ async def binary_sensor_is_off_to_code(config, condition_id, template_arg, args)
652
652
  return cg.new_Pvariable(condition_id, template_arg, paren, False)
653
653
 
654
654
 
655
- @coroutine_with_priority(100.0)
655
+ @coroutine_with_priority(CoroPriority.CORE)
656
656
  async def to_code(config):
657
657
  cg.add_global(binary_sensor_ns.using)
658
658
 
@@ -7,6 +7,19 @@ namespace binary_sensor {
7
7
 
8
8
  static const char *const TAG = "binary_sensor";
9
9
 
10
+ // Function implementation of LOG_BINARY_SENSOR macro to reduce code size
11
+ void log_binary_sensor(const char *tag, const char *prefix, const char *type, BinarySensor *obj) {
12
+ if (obj == nullptr) {
13
+ return;
14
+ }
15
+
16
+ ESP_LOGCONFIG(tag, "%s%s '%s'", prefix, type, obj->get_name().c_str());
17
+
18
+ if (!obj->get_device_class_ref().empty()) {
19
+ ESP_LOGCONFIG(tag, "%s Device Class: '%s'", prefix, obj->get_device_class_ref().c_str());
20
+ }
21
+ }
22
+
10
23
  void BinarySensor::publish_state(bool new_state) {
11
24
  if (this->filter_list_ == nullptr) {
12
25
  this->send_state_internal(new_state);
@@ -10,13 +10,10 @@ namespace esphome {
10
10
 
11
11
  namespace binary_sensor {
12
12
 
13
- #define LOG_BINARY_SENSOR(prefix, type, obj) \
14
- if ((obj) != nullptr) { \
15
- ESP_LOGCONFIG(TAG, "%s%s '%s'", prefix, LOG_STR_LITERAL(type), (obj)->get_name().c_str()); \
16
- if (!(obj)->get_device_class().empty()) { \
17
- ESP_LOGCONFIG(TAG, "%s Device Class: '%s'", prefix, (obj)->get_device_class().c_str()); \
18
- } \
19
- }
13
+ class BinarySensor;
14
+ void log_binary_sensor(const char *tag, const char *prefix, const char *type, BinarySensor *obj);
15
+
16
+ #define LOG_BINARY_SENSOR(prefix, type, obj) log_binary_sensor(TAG, prefix, LOG_STR_LITERAL(type), obj)
20
17
 
21
18
  #define SUB_BINARY_SENSOR(name) \
22
19
  protected: \
@@ -1 +1,6 @@
1
- CODEOWNERS = ["@tobias-"]
1
+ import esphome.codegen as cg
2
+
3
+ CODEOWNERS = ["@tobias-", "@dan-s-github"]
4
+
5
+ CONF_BL0940_ID = "bl0940_id"
6
+ bl0940_ns = cg.esphome_ns.namespace("bl0940")
@@ -7,28 +7,26 @@ namespace bl0940 {
7
7
 
8
8
  static const char *const TAG = "bl0940";
9
9
 
10
- static const uint8_t BL0940_READ_COMMAND = 0x50; // 0x58 according to documentation
11
10
  static const uint8_t BL0940_FULL_PACKET = 0xAA;
12
- static const uint8_t BL0940_PACKET_HEADER = 0x55; // 0x58 according to documentation
11
+ static const uint8_t BL0940_PACKET_HEADER = 0x55; // 0x58 according to en doc but 0x55 in cn doc
13
12
 
14
- static const uint8_t BL0940_WRITE_COMMAND = 0xA0; // 0xA8 according to documentation
15
13
  static const uint8_t BL0940_REG_I_FAST_RMS_CTRL = 0x10;
16
14
  static const uint8_t BL0940_REG_MODE = 0x18;
17
15
  static const uint8_t BL0940_REG_SOFT_RESET = 0x19;
18
16
  static const uint8_t BL0940_REG_USR_WRPROT = 0x1A;
19
17
  static const uint8_t BL0940_REG_TPS_CTRL = 0x1B;
20
18
 
21
- const uint8_t BL0940_INIT[5][6] = {
19
+ static const uint8_t BL0940_INIT[5][5] = {
22
20
  // Reset to default
23
- {BL0940_WRITE_COMMAND, BL0940_REG_SOFT_RESET, 0x5A, 0x5A, 0x5A, 0x38},
21
+ {BL0940_REG_SOFT_RESET, 0x5A, 0x5A, 0x5A, 0x38},
24
22
  // Enable User Operation Write
25
- {BL0940_WRITE_COMMAND, BL0940_REG_USR_WRPROT, 0x55, 0x00, 0x00, 0xF0},
23
+ {BL0940_REG_USR_WRPROT, 0x55, 0x00, 0x00, 0xF0},
26
24
  // 0x0100 = CF_UNABLE energy pulse, AC_FREQ_SEL 50Hz, RMS_UPDATE_SEL 800mS
27
- {BL0940_WRITE_COMMAND, BL0940_REG_MODE, 0x00, 0x10, 0x00, 0x37},
25
+ {BL0940_REG_MODE, 0x00, 0x10, 0x00, 0x37},
28
26
  // 0x47FF = Over-current and leakage alarm on, Automatic temperature measurement, Interval 100mS
29
- {BL0940_WRITE_COMMAND, BL0940_REG_TPS_CTRL, 0xFF, 0x47, 0x00, 0xFE},
27
+ {BL0940_REG_TPS_CTRL, 0xFF, 0x47, 0x00, 0xFE},
30
28
  // 0x181C = Half cycle, Fast RMS threshold 6172
31
- {BL0940_WRITE_COMMAND, BL0940_REG_I_FAST_RMS_CTRL, 0x1C, 0x18, 0x00, 0x1B}};
29
+ {BL0940_REG_I_FAST_RMS_CTRL, 0x1C, 0x18, 0x00, 0x1B}};
32
30
 
33
31
  void BL0940::loop() {
34
32
  DataPacket buffer;
@@ -36,8 +34,8 @@ void BL0940::loop() {
36
34
  return;
37
35
  }
38
36
  if (read_array((uint8_t *) &buffer, sizeof(buffer))) {
39
- if (validate_checksum(&buffer)) {
40
- received_package_(&buffer);
37
+ if (this->validate_checksum_(&buffer)) {
38
+ this->received_package_(&buffer);
41
39
  }
42
40
  } else {
43
41
  ESP_LOGW(TAG, "Junk on wire. Throwing away partial message");
@@ -46,35 +44,151 @@ void BL0940::loop() {
46
44
  }
47
45
  }
48
46
 
49
- bool BL0940::validate_checksum(const DataPacket *data) {
50
- uint8_t checksum = BL0940_READ_COMMAND;
47
+ bool BL0940::validate_checksum_(DataPacket *data) {
48
+ uint8_t checksum = this->read_command_;
51
49
  // Whole package but checksum
52
- for (uint32_t i = 0; i < sizeof(data->raw) - 1; i++) {
53
- checksum += data->raw[i];
50
+ uint8_t *raw = (uint8_t *) data;
51
+ for (uint32_t i = 0; i < sizeof(*data) - 1; i++) {
52
+ checksum += raw[i];
54
53
  }
55
54
  checksum ^= 0xFF;
56
55
  if (checksum != data->checksum) {
57
- ESP_LOGW(TAG, "BL0940 invalid checksum! 0x%02X != 0x%02X", checksum, data->checksum);
56
+ ESP_LOGW(TAG, "Invalid checksum! 0x%02X != 0x%02X", checksum, data->checksum);
58
57
  }
59
58
  return checksum == data->checksum;
60
59
  }
61
60
 
62
61
  void BL0940::update() {
63
62
  this->flush();
64
- this->write_byte(BL0940_READ_COMMAND);
63
+ this->write_byte(this->read_command_);
65
64
  this->write_byte(BL0940_FULL_PACKET);
66
65
  }
67
66
 
68
67
  void BL0940::setup() {
68
+ #ifdef USE_NUMBER
69
+ // add calibration callbacks
70
+ if (this->voltage_calibration_number_ != nullptr) {
71
+ this->voltage_calibration_number_->add_on_state_callback(
72
+ [this](float state) { this->voltage_calibration_callback_(state); });
73
+ if (this->voltage_calibration_number_->has_state()) {
74
+ this->voltage_calibration_callback_(this->voltage_calibration_number_->state);
75
+ }
76
+ }
77
+
78
+ if (this->current_calibration_number_ != nullptr) {
79
+ this->current_calibration_number_->add_on_state_callback(
80
+ [this](float state) { this->current_calibration_callback_(state); });
81
+ if (this->current_calibration_number_->has_state()) {
82
+ this->current_calibration_callback_(this->current_calibration_number_->state);
83
+ }
84
+ }
85
+
86
+ if (this->power_calibration_number_ != nullptr) {
87
+ this->power_calibration_number_->add_on_state_callback(
88
+ [this](float state) { this->power_calibration_callback_(state); });
89
+ if (this->power_calibration_number_->has_state()) {
90
+ this->power_calibration_callback_(this->power_calibration_number_->state);
91
+ }
92
+ }
93
+
94
+ if (this->energy_calibration_number_ != nullptr) {
95
+ this->energy_calibration_number_->add_on_state_callback(
96
+ [this](float state) { this->energy_calibration_callback_(state); });
97
+ if (this->energy_calibration_number_->has_state()) {
98
+ this->energy_calibration_callback_(this->energy_calibration_number_->state);
99
+ }
100
+ }
101
+ #endif
102
+
103
+ // calculate calibrated reference values
104
+ this->voltage_reference_cal_ = this->voltage_reference_ / this->voltage_cal_;
105
+ this->current_reference_cal_ = this->current_reference_ / this->current_cal_;
106
+ this->power_reference_cal_ = this->power_reference_ / this->power_cal_;
107
+ this->energy_reference_cal_ = this->energy_reference_ / this->energy_cal_;
108
+
69
109
  for (auto *i : BL0940_INIT) {
70
- this->write_array(i, 6);
110
+ this->write_byte(this->write_command_), this->write_array(i, 5);
71
111
  delay(1);
72
112
  }
73
113
  this->flush();
74
114
  }
75
115
 
76
- float BL0940::update_temp_(sensor::Sensor *sensor, ube16_t temperature) const {
77
- auto tb = (float) (temperature.h << 8 | temperature.l);
116
+ float BL0940::calculate_power_reference_() {
117
+ // calculate power reference based on voltage and current reference
118
+ return this->voltage_reference_cal_ * this->current_reference_cal_ * 4046 / 324004 / 79931;
119
+ }
120
+
121
+ float BL0940::calculate_energy_reference_() {
122
+ // formula: 3600000 * 4046 * RL * R1 * 1000 / (1638.4 * 256) / Vref² / (R1 + R2)
123
+ // or: power_reference_ * 3600000 / (1638.4 * 256)
124
+ return this->power_reference_cal_ * 3600000 / (1638.4 * 256);
125
+ }
126
+
127
+ float BL0940::calculate_calibration_value_(float state) { return (100 + state) / 100; }
128
+
129
+ void BL0940::reset_calibration() {
130
+ #ifdef USE_NUMBER
131
+ if (this->current_calibration_number_ != nullptr && this->current_cal_ != 1) {
132
+ this->current_calibration_number_->make_call().set_value(0).perform();
133
+ }
134
+ if (this->voltage_calibration_number_ != nullptr && this->voltage_cal_ != 1) {
135
+ this->voltage_calibration_number_->make_call().set_value(0).perform();
136
+ }
137
+ if (this->power_calibration_number_ != nullptr && this->power_cal_ != 1) {
138
+ this->power_calibration_number_->make_call().set_value(0).perform();
139
+ }
140
+ if (this->energy_calibration_number_ != nullptr && this->energy_cal_ != 1) {
141
+ this->energy_calibration_number_->make_call().set_value(0).perform();
142
+ }
143
+ #endif
144
+ ESP_LOGD(TAG, "external calibration values restored to initial state");
145
+ }
146
+
147
+ void BL0940::current_calibration_callback_(float state) {
148
+ this->current_cal_ = this->calculate_calibration_value_(state);
149
+ ESP_LOGV(TAG, "update current calibration state: %f", this->current_cal_);
150
+ this->recalibrate_();
151
+ }
152
+ void BL0940::voltage_calibration_callback_(float state) {
153
+ this->voltage_cal_ = this->calculate_calibration_value_(state);
154
+ ESP_LOGV(TAG, "update voltage calibration state: %f", this->voltage_cal_);
155
+ this->recalibrate_();
156
+ }
157
+ void BL0940::power_calibration_callback_(float state) {
158
+ this->power_cal_ = this->calculate_calibration_value_(state);
159
+ ESP_LOGV(TAG, "update power calibration state: %f", this->power_cal_);
160
+ this->recalibrate_();
161
+ }
162
+ void BL0940::energy_calibration_callback_(float state) {
163
+ this->energy_cal_ = this->calculate_calibration_value_(state);
164
+ ESP_LOGV(TAG, "update energy calibration state: %f", this->energy_cal_);
165
+ this->recalibrate_();
166
+ }
167
+
168
+ void BL0940::recalibrate_() {
169
+ ESP_LOGV(TAG, "Recalibrating reference values");
170
+ this->voltage_reference_cal_ = this->voltage_reference_ / this->voltage_cal_;
171
+ this->current_reference_cal_ = this->current_reference_ / this->current_cal_;
172
+
173
+ if (this->voltage_cal_ != 1 || this->current_cal_ != 1) {
174
+ this->power_reference_ = this->calculate_power_reference_();
175
+ }
176
+ this->power_reference_cal_ = this->power_reference_ / this->power_cal_;
177
+
178
+ if (this->voltage_cal_ != 1 || this->current_cal_ != 1 || this->power_cal_ != 1) {
179
+ this->energy_reference_ = this->calculate_energy_reference_();
180
+ }
181
+ this->energy_reference_cal_ = this->energy_reference_ / this->energy_cal_;
182
+
183
+ ESP_LOGD(TAG,
184
+ "Recalibrated reference values:\n"
185
+ "Voltage: %f\n, Current: %f\n, Power: %f\n, Energy: %f\n",
186
+ this->voltage_reference_cal_, this->current_reference_cal_, this->power_reference_cal_,
187
+ this->energy_reference_cal_);
188
+ }
189
+
190
+ float BL0940::update_temp_(sensor::Sensor *sensor, uint16_le_t temperature) const {
191
+ auto tb = (float) temperature;
78
192
  float converted_temp = ((float) 170 / 448) * (tb / 2 - 32) - 45;
79
193
  if (sensor != nullptr) {
80
194
  if (sensor->has_state() && std::abs(converted_temp - sensor->get_state()) > max_temperature_diff_) {
@@ -87,33 +201,40 @@ float BL0940::update_temp_(sensor::Sensor *sensor, ube16_t temperature) const {
87
201
  return converted_temp;
88
202
  }
89
203
 
90
- void BL0940::received_package_(const DataPacket *data) const {
204
+ void BL0940::received_package_(DataPacket *data) {
91
205
  // Bad header
92
206
  if (data->frame_header != BL0940_PACKET_HEADER) {
93
207
  ESP_LOGI(TAG, "Invalid data. Header mismatch: %d", data->frame_header);
94
208
  return;
95
209
  }
96
210
 
97
- float v_rms = (float) to_uint32_t(data->v_rms) / voltage_reference_;
98
- float i_rms = (float) to_uint32_t(data->i_rms) / current_reference_;
99
- float watt = (float) to_int32_t(data->watt) / power_reference_;
100
- uint32_t cf_cnt = to_uint32_t(data->cf_cnt);
101
- float total_energy_consumption = (float) cf_cnt / energy_reference_;
211
+ // cf_cnt is only 24 bits, so track overflows
212
+ uint32_t cf_cnt = (uint24_t) data->cf_cnt;
213
+ cf_cnt |= this->prev_cf_cnt_ & 0xff000000;
214
+ if (cf_cnt < this->prev_cf_cnt_) {
215
+ cf_cnt += 0x1000000;
216
+ }
217
+ this->prev_cf_cnt_ = cf_cnt;
218
+
219
+ float v_rms = (uint24_t) data->v_rms / this->voltage_reference_cal_;
220
+ float i_rms = (uint24_t) data->i_rms / this->current_reference_cal_;
221
+ float watt = (int24_t) data->watt / this->power_reference_cal_;
222
+ float total_energy_consumption = cf_cnt / this->energy_reference_cal_;
102
223
 
103
- float tps1 = update_temp_(internal_temperature_sensor_, data->tps1);
104
- float tps2 = update_temp_(external_temperature_sensor_, data->tps2);
224
+ float tps1 = update_temp_(this->internal_temperature_sensor_, data->tps1);
225
+ float tps2 = update_temp_(this->external_temperature_sensor_, data->tps2);
105
226
 
106
- if (voltage_sensor_ != nullptr) {
107
- voltage_sensor_->publish_state(v_rms);
227
+ if (this->voltage_sensor_ != nullptr) {
228
+ this->voltage_sensor_->publish_state(v_rms);
108
229
  }
109
- if (current_sensor_ != nullptr) {
110
- current_sensor_->publish_state(i_rms);
230
+ if (this->current_sensor_ != nullptr) {
231
+ this->current_sensor_->publish_state(i_rms);
111
232
  }
112
- if (power_sensor_ != nullptr) {
113
- power_sensor_->publish_state(watt);
233
+ if (this->power_sensor_ != nullptr) {
234
+ this->power_sensor_->publish_state(watt);
114
235
  }
115
- if (energy_sensor_ != nullptr) {
116
- energy_sensor_->publish_state(total_energy_consumption);
236
+ if (this->energy_sensor_ != nullptr) {
237
+ this->energy_sensor_->publish_state(total_energy_consumption);
117
238
  }
118
239
 
119
240
  ESP_LOGV(TAG, "BL0940: U %fV, I %fA, P %fW, Cnt %" PRId32 ", ∫P %fkWh, T1 %f°C, T2 %f°C", v_rms, i_rms, watt, cf_cnt,
@@ -121,7 +242,27 @@ void BL0940::received_package_(const DataPacket *data) const {
121
242
  }
122
243
 
123
244
  void BL0940::dump_config() { // NOLINT(readability-function-cognitive-complexity)
124
- ESP_LOGCONFIG(TAG, "BL0940:");
245
+ ESP_LOGCONFIG(TAG,
246
+ "BL0940:\n"
247
+ " LEGACY MODE: %s\n"
248
+ " READ CMD: 0x%02X\n"
249
+ " WRITE CMD: 0x%02X\n"
250
+ " ------------------\n"
251
+ " Current reference: %f\n"
252
+ " Energy reference: %f\n"
253
+ " Power reference: %f\n"
254
+ " Voltage reference: %f\n",
255
+ TRUEFALSE(this->legacy_mode_enabled_), this->read_command_, this->write_command_,
256
+ this->current_reference_, this->energy_reference_, this->power_reference_, this->voltage_reference_);
257
+ #ifdef USE_NUMBER
258
+ ESP_LOGCONFIG(TAG,
259
+ "BL0940:\n"
260
+ " Current calibration: %f\n"
261
+ " Energy calibration: %f\n"
262
+ " Power calibration: %f\n"
263
+ " Voltage calibration: %f\n",
264
+ this->current_cal_, this->energy_cal_, this->power_cal_, this->voltage_cal_);
265
+ #endif
125
266
  LOG_SENSOR("", "Voltage", this->voltage_sensor_);
126
267
  LOG_SENSOR("", "Current", this->current_sensor_);
127
268
  LOG_SENSOR("", "Power", this->power_sensor_);
@@ -130,9 +271,5 @@ void BL0940::dump_config() { // NOLINT(readability-function-cognitive-complexit
130
271
  LOG_SENSOR("", "External temperature", this->external_temperature_sensor_);
131
272
  }
132
273
 
133
- uint32_t BL0940::to_uint32_t(ube24_t input) { return input.h << 16 | input.m << 8 | input.l; }
134
-
135
- int32_t BL0940::to_int32_t(sbe24_t input) { return input.h << 16 | input.m << 8 | input.l; }
136
-
137
274
  } // namespace bl0940
138
275
  } // namespace esphome