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
@@ -1,66 +1,48 @@
1
1
  #pragma once
2
2
 
3
3
  #include "esphome/core/component.h"
4
- #include "esphome/components/uart/uart.h"
4
+ #include "esphome/core/datatypes.h"
5
+ #include "esphome/core/defines.h"
6
+ #ifdef USE_BUTTON
7
+ #include "esphome/components/button/button.h"
8
+ #endif
9
+ #ifdef USE_NUMBER
10
+ #include "esphome/components/number/number.h"
11
+ #endif
5
12
  #include "esphome/components/sensor/sensor.h"
13
+ #include "esphome/components/uart/uart.h"
6
14
 
7
15
  namespace esphome {
8
16
  namespace bl0940 {
9
17
 
10
- static const float BL0940_PREF = 1430;
11
- static const float BL0940_UREF = 33000;
12
- static const float BL0940_IREF = 275000; // 2750 from tasmota. Seems to generate values 100 times too high
13
-
14
- // Measured to 297J per click according to power consumption of 5 minutes
15
- // Converted to kWh (3.6MJ per kwH). Used to be 256 * 1638.4
16
- static const float BL0940_EREF = 3.6e6 / 297;
17
-
18
- struct ube24_t { // NOLINT(readability-identifier-naming,altera-struct-pack-align)
19
- uint8_t l;
20
- uint8_t m;
21
- uint8_t h;
22
- } __attribute__((packed));
23
-
24
- struct ube16_t { // NOLINT(readability-identifier-naming,altera-struct-pack-align)
25
- uint8_t l;
26
- uint8_t h;
27
- } __attribute__((packed));
28
-
29
- struct sbe24_t { // NOLINT(readability-identifier-naming,altera-struct-pack-align)
30
- uint8_t l;
31
- uint8_t m;
32
- int8_t h;
33
- } __attribute__((packed));
34
-
35
18
  // Caveat: All these values are big endian (low - middle - high)
36
-
37
- union DataPacket { // NOLINT(altera-struct-pack-align)
38
- uint8_t raw[35];
39
- struct {
40
- uint8_t frame_header; // value of 0x58 according to docs. 0x55 according to Tasmota real world tests. Reality wins.
41
- ube24_t i_fast_rms; // 0x00
42
- ube24_t i_rms; // 0x04
43
- ube24_t RESERVED0; // reserved
44
- ube24_t v_rms; // 0x06
45
- ube24_t RESERVED1; // reserved
46
- sbe24_t watt; // 0x08
47
- ube24_t RESERVED2; // reserved
48
- ube24_t cf_cnt; // 0x0A
49
- ube24_t RESERVED3; // reserved
50
- ube16_t tps1; // 0x0c
51
- uint8_t RESERVED4; // value of 0x00
52
- ube16_t tps2; // 0x0c
53
- uint8_t RESERVED5; // value of 0x00
54
- uint8_t checksum; // checksum
55
- };
19
+ struct DataPacket {
20
+ uint8_t frame_header; // Packet header (0x58 in EN docs, 0x55 in CN docs and Tasmota tests)
21
+ uint24_le_t i_fast_rms; // Fast RMS current
22
+ uint24_le_t i_rms; // RMS current
23
+ uint24_t RESERVED0; // Reserved
24
+ uint24_le_t v_rms; // RMS voltage
25
+ uint24_t RESERVED1; // Reserved
26
+ int24_le_t watt; // Active power (can be negative for bidirectional measurement)
27
+ uint24_t RESERVED2; // Reserved
28
+ uint24_le_t cf_cnt; // Energy pulse count
29
+ uint24_t RESERVED3; // Reserved
30
+ uint16_le_t tps1; // Internal temperature sensor 1
31
+ uint8_t RESERVED4; // Reserved (should be 0x00)
32
+ uint16_le_t tps2; // Internal temperature sensor 2
33
+ uint8_t RESERVED5; // Reserved (should be 0x00)
34
+ uint8_t checksum; // Packet checksum
56
35
  } __attribute__((packed));
57
36
 
58
37
  class BL0940 : public PollingComponent, public uart::UARTDevice {
59
38
  public:
39
+ // Sensor setters
60
40
  void set_voltage_sensor(sensor::Sensor *voltage_sensor) { voltage_sensor_ = voltage_sensor; }
61
41
  void set_current_sensor(sensor::Sensor *current_sensor) { current_sensor_ = current_sensor; }
62
42
  void set_power_sensor(sensor::Sensor *power_sensor) { power_sensor_ = power_sensor; }
63
43
  void set_energy_sensor(sensor::Sensor *energy_sensor) { energy_sensor_ = energy_sensor; }
44
+
45
+ // Temperature sensor setters
64
46
  void set_internal_temperature_sensor(sensor::Sensor *internal_temperature_sensor) {
65
47
  internal_temperature_sensor_ = internal_temperature_sensor;
66
48
  }
@@ -68,42 +50,105 @@ class BL0940 : public PollingComponent, public uart::UARTDevice {
68
50
  external_temperature_sensor_ = external_temperature_sensor;
69
51
  }
70
52
 
53
+ // Configuration setters
54
+ void set_legacy_mode(bool enable) { this->legacy_mode_enabled_ = enable; }
55
+ void set_read_command(uint8_t read_command) { this->read_command_ = read_command; }
56
+ void set_write_command(uint8_t write_command) { this->write_command_ = write_command; }
57
+
58
+ // Reference value setters (used for calibration and conversion)
59
+ void set_current_reference(float current_ref) { this->current_reference_ = current_ref; }
60
+ void set_energy_reference(float energy_ref) { this->energy_reference_ = energy_ref; }
61
+ void set_power_reference(float power_ref) { this->power_reference_ = power_ref; }
62
+ void set_voltage_reference(float voltage_ref) { this->voltage_reference_ = voltage_ref; }
63
+
64
+ #ifdef USE_NUMBER
65
+ // Calibration number setters (for Home Assistant number entities)
66
+ void set_current_calibration_number(number::Number *num) { this->current_calibration_number_ = num; }
67
+ void set_voltage_calibration_number(number::Number *num) { this->voltage_calibration_number_ = num; }
68
+ void set_power_calibration_number(number::Number *num) { this->power_calibration_number_ = num; }
69
+ void set_energy_calibration_number(number::Number *num) { this->energy_calibration_number_ = num; }
70
+ #endif
71
+
72
+ #ifdef USE_BUTTON
73
+ // Resets all calibration values to defaults (can be triggered by a button)
74
+ void reset_calibration();
75
+ #endif
76
+
77
+ // Core component methods
71
78
  void loop() override;
72
-
73
79
  void update() override;
74
80
  void setup() override;
75
81
  void dump_config() override;
76
82
 
77
83
  protected:
78
- sensor::Sensor *voltage_sensor_{nullptr};
79
- sensor::Sensor *current_sensor_{nullptr};
80
- // NB This may be negative as the circuits is seemingly able to measure
81
- // power in both directions
82
- sensor::Sensor *power_sensor_{nullptr};
83
- sensor::Sensor *energy_sensor_{nullptr};
84
- sensor::Sensor *internal_temperature_sensor_{nullptr};
85
- sensor::Sensor *external_temperature_sensor_{nullptr};
86
-
87
- // Max difference between two measurements of the temperature. Used to avoid noise.
88
- float max_temperature_diff_{0};
89
- // Divide by this to turn into Watt
90
- float power_reference_ = BL0940_PREF;
91
- // Divide by this to turn into Volt
92
- float voltage_reference_ = BL0940_UREF;
93
- // Divide by this to turn into Ampere
94
- float current_reference_ = BL0940_IREF;
95
- // Divide by this to turn into kWh
96
- float energy_reference_ = BL0940_EREF;
97
-
98
- float update_temp_(sensor::Sensor *sensor, ube16_t packed_temperature) const;
99
-
100
- static uint32_t to_uint32_t(ube24_t input);
101
-
102
- static int32_t to_int32_t(sbe24_t input);
103
-
104
- static bool validate_checksum(const DataPacket *data);
105
-
106
- void received_package_(const DataPacket *data) const;
84
+ // --- Sensor pointers ---
85
+ sensor::Sensor *voltage_sensor_{nullptr}; // Voltage sensor
86
+ sensor::Sensor *current_sensor_{nullptr}; // Current sensor
87
+ sensor::Sensor *power_sensor_{nullptr}; // Power sensor (can be negative for bidirectional)
88
+ sensor::Sensor *energy_sensor_{nullptr}; // Energy sensor
89
+ sensor::Sensor *internal_temperature_sensor_{nullptr}; // Internal temperature sensor
90
+ sensor::Sensor *external_temperature_sensor_{nullptr}; // External temperature sensor
91
+
92
+ #ifdef USE_NUMBER
93
+ // --- Calibration number entities (for dynamic calibration via HA UI) ---
94
+ number::Number *voltage_calibration_number_{nullptr};
95
+ number::Number *current_calibration_number_{nullptr};
96
+ number::Number *power_calibration_number_{nullptr};
97
+ number::Number *energy_calibration_number_{nullptr};
98
+ #endif
99
+
100
+ // --- Internal state ---
101
+ uint32_t prev_cf_cnt_ = 0; // Previous energy pulse count (for energy calculation)
102
+ float max_temperature_diff_{0}; // Max allowed temperature difference between two measurements (noise filter)
103
+
104
+ // --- Reference values for conversion ---
105
+ float power_reference_; // Divider for raw power to get Watts
106
+ float power_reference_cal_; // Calibrated power reference
107
+ float voltage_reference_; // Divider for raw voltage to get Volts
108
+ float voltage_reference_cal_; // Calibrated voltage reference
109
+ float current_reference_; // Divider for raw current to get Amperes
110
+ float current_reference_cal_; // Calibrated current reference
111
+ float energy_reference_; // Divider for raw energy to get kWh
112
+ float energy_reference_cal_; // Calibrated energy reference
113
+
114
+ // --- Home Assistant calibration values (multipliers, default 1) ---
115
+ float current_cal_{1};
116
+ float voltage_cal_{1};
117
+ float power_cal_{1};
118
+ float energy_cal_{1};
119
+
120
+ // --- Protocol commands ---
121
+ uint8_t read_command_;
122
+ uint8_t write_command_;
123
+
124
+ // --- Mode flags ---
125
+ bool legacy_mode_enabled_ = true;
126
+
127
+ // --- Methods ---
128
+ // Converts packed temperature value to float and updates the sensor
129
+ float update_temp_(sensor::Sensor *sensor, uint16_le_t packed_temperature) const;
130
+
131
+ // Validates the checksum of a received data packet
132
+ bool validate_checksum_(DataPacket *data);
133
+
134
+ // Handles a received data packet
135
+ void received_package_(DataPacket *data);
136
+
137
+ // Calculates reference values for calibration and conversion
138
+ float calculate_energy_reference_();
139
+ float calculate_power_reference_();
140
+ float calculate_calibration_value_(float state);
141
+
142
+ // Calibration update callbacks (used with number entities)
143
+ void current_calibration_callback_(float state);
144
+ void voltage_calibration_callback_(float state);
145
+ void power_calibration_callback_(float state);
146
+ void energy_calibration_callback_(float state);
147
+ void reset_calibration_callback_();
148
+
149
+ // Recalculates all reference values after calibration changes
150
+ void recalibrate_();
107
151
  };
152
+
108
153
  } // namespace bl0940
109
154
  } // namespace esphome
@@ -0,0 +1,27 @@
1
+ import esphome.codegen as cg
2
+ from esphome.components import button
3
+ import esphome.config_validation as cv
4
+ from esphome.const import ENTITY_CATEGORY_CONFIG, ICON_RESTART
5
+
6
+ from .. import CONF_BL0940_ID, bl0940_ns
7
+ from ..sensor import BL0940
8
+
9
+ CalibrationResetButton = bl0940_ns.class_(
10
+ "CalibrationResetButton", button.Button, cg.Component
11
+ )
12
+
13
+ CONFIG_SCHEMA = cv.All(
14
+ button.button_schema(
15
+ CalibrationResetButton,
16
+ entity_category=ENTITY_CATEGORY_CONFIG,
17
+ icon=ICON_RESTART,
18
+ )
19
+ .extend({cv.GenerateID(CONF_BL0940_ID): cv.use_id(BL0940)})
20
+ .extend(cv.COMPONENT_SCHEMA)
21
+ )
22
+
23
+
24
+ async def to_code(config):
25
+ var = await button.new_button(config)
26
+ await cg.register_component(var, config)
27
+ await cg.register_parented(var, config[CONF_BL0940_ID])
@@ -0,0 +1,20 @@
1
+ #include "calibration_reset_button.h"
2
+ #include "../bl0940.h"
3
+ #include "esphome/core/hal.h"
4
+ #include "esphome/core/log.h"
5
+ #include "esphome/core/application.h"
6
+
7
+ namespace esphome {
8
+ namespace bl0940 {
9
+
10
+ static const char *const TAG = "bl0940.button.calibration_reset";
11
+
12
+ void CalibrationResetButton::dump_config() { LOG_BUTTON("", "Calibration Reset Button", this); }
13
+
14
+ void CalibrationResetButton::press_action() {
15
+ ESP_LOGI(TAG, "Resetting calibration defaults...");
16
+ this->parent_->reset_calibration();
17
+ }
18
+
19
+ } // namespace bl0940
20
+ } // namespace esphome
@@ -0,0 +1,19 @@
1
+ #pragma once
2
+
3
+ #include "esphome/core/component.h"
4
+ #include "esphome/components/button/button.h"
5
+
6
+ namespace esphome {
7
+ namespace bl0940 {
8
+
9
+ class BL0940; // Forward declaration of BL0940 class
10
+
11
+ class CalibrationResetButton : public button::Button, public Component, public Parented<BL0940> {
12
+ public:
13
+ void dump_config() override;
14
+
15
+ void press_action() override;
16
+ };
17
+
18
+ } // namespace bl0940
19
+ } // namespace esphome
@@ -0,0 +1,94 @@
1
+ import esphome.codegen as cg
2
+ from esphome.components import number
3
+ import esphome.config_validation as cv
4
+ from esphome.const import (
5
+ CONF_MAX_VALUE,
6
+ CONF_MIN_VALUE,
7
+ CONF_MODE,
8
+ CONF_RESTORE_VALUE,
9
+ CONF_STEP,
10
+ ENTITY_CATEGORY_CONFIG,
11
+ UNIT_PERCENT,
12
+ )
13
+
14
+ from .. import CONF_BL0940_ID, bl0940_ns
15
+ from ..sensor import BL0940
16
+
17
+ # Define calibration types
18
+ CONF_CURRENT_CALIBRATION = "current_calibration"
19
+ CONF_VOLTAGE_CALIBRATION = "voltage_calibration"
20
+ CONF_POWER_CALIBRATION = "power_calibration"
21
+ CONF_ENERGY_CALIBRATION = "energy_calibration"
22
+
23
+ BL0940Number = bl0940_ns.class_("BL0940Number")
24
+
25
+ CalibrationNumber = bl0940_ns.class_(
26
+ "CalibrationNumber", number.Number, cg.PollingComponent
27
+ )
28
+
29
+
30
+ def validate_min_max(config):
31
+ if config[CONF_MAX_VALUE] <= config[CONF_MIN_VALUE]:
32
+ raise cv.Invalid("max_value must be greater than min_value")
33
+ return config
34
+
35
+
36
+ CALIBRATION_SCHEMA = cv.All(
37
+ number.number_schema(
38
+ CalibrationNumber,
39
+ entity_category=ENTITY_CATEGORY_CONFIG,
40
+ unit_of_measurement=UNIT_PERCENT,
41
+ )
42
+ .extend(
43
+ {
44
+ cv.Optional(CONF_MODE, default="BOX"): cv.enum(number.NUMBER_MODES),
45
+ cv.Optional(CONF_MAX_VALUE, default=10): cv.All(
46
+ cv.float_, cv.Range(max=50)
47
+ ),
48
+ cv.Optional(CONF_MIN_VALUE, default=-10): cv.All(
49
+ cv.float_, cv.Range(min=-50)
50
+ ),
51
+ cv.Optional(CONF_STEP, default=0.1): cv.positive_float,
52
+ cv.Optional(CONF_RESTORE_VALUE): cv.boolean,
53
+ }
54
+ )
55
+ .extend(cv.COMPONENT_SCHEMA),
56
+ validate_min_max,
57
+ )
58
+
59
+ # Configuration schema for BL0940 numbers
60
+ CONFIG_SCHEMA = cv.Schema(
61
+ {
62
+ cv.GenerateID(): cv.declare_id(BL0940Number),
63
+ cv.GenerateID(CONF_BL0940_ID): cv.use_id(BL0940),
64
+ cv.Optional(CONF_CURRENT_CALIBRATION): CALIBRATION_SCHEMA,
65
+ cv.Optional(CONF_VOLTAGE_CALIBRATION): CALIBRATION_SCHEMA,
66
+ cv.Optional(CONF_POWER_CALIBRATION): CALIBRATION_SCHEMA,
67
+ cv.Optional(CONF_ENERGY_CALIBRATION): CALIBRATION_SCHEMA,
68
+ }
69
+ )
70
+
71
+
72
+ async def to_code(config):
73
+ # Get the BL0940 component instance
74
+ bl0940 = await cg.get_variable(config[CONF_BL0940_ID])
75
+
76
+ # Process all calibration types
77
+ for cal_type, setter_method in [
78
+ (CONF_CURRENT_CALIBRATION, "set_current_calibration_number"),
79
+ (CONF_VOLTAGE_CALIBRATION, "set_voltage_calibration_number"),
80
+ (CONF_POWER_CALIBRATION, "set_power_calibration_number"),
81
+ (CONF_ENERGY_CALIBRATION, "set_energy_calibration_number"),
82
+ ]:
83
+ if conf := config.get(cal_type):
84
+ var = await number.new_number(
85
+ conf,
86
+ min_value=conf.get(CONF_MIN_VALUE),
87
+ max_value=conf.get(CONF_MAX_VALUE),
88
+ step=conf.get(CONF_STEP),
89
+ )
90
+ await cg.register_component(var, conf)
91
+
92
+ if restore_value := config.get(CONF_RESTORE_VALUE):
93
+ cg.add(var.set_restore_value(restore_value))
94
+ cg.add(getattr(bl0940, setter_method)(var))
@@ -0,0 +1,29 @@
1
+ #include "calibration_number.h"
2
+ #include "esphome/core/log.h"
3
+
4
+ namespace esphome {
5
+ namespace bl0940 {
6
+
7
+ static const char *const TAG = "bl0940.number";
8
+
9
+ void CalibrationNumber::setup() {
10
+ float value = 0.0f;
11
+ if (this->restore_value_) {
12
+ this->pref_ = global_preferences->make_preference<float>(this->get_object_id_hash());
13
+ if (!this->pref_.load(&value)) {
14
+ value = 0.0f;
15
+ }
16
+ }
17
+ this->publish_state(value);
18
+ }
19
+
20
+ void CalibrationNumber::control(float value) {
21
+ this->publish_state(value);
22
+ if (this->restore_value_)
23
+ this->pref_.save(&value);
24
+ }
25
+
26
+ void CalibrationNumber::dump_config() { LOG_NUMBER("", "Calibration Number", this); }
27
+
28
+ } // namespace bl0940
29
+ } // namespace esphome
@@ -0,0 +1,26 @@
1
+ #pragma once
2
+
3
+ #include "esphome/components/number/number.h"
4
+ #include "esphome/core/component.h"
5
+ #include "esphome/core/preferences.h"
6
+
7
+ namespace esphome {
8
+ namespace bl0940 {
9
+
10
+ class CalibrationNumber : public number::Number, public Component {
11
+ public:
12
+ void setup() override;
13
+ void dump_config() override;
14
+ float get_setup_priority() const override { return setup_priority::HARDWARE; }
15
+
16
+ void set_restore_value(bool restore_value) { this->restore_value_ = restore_value; }
17
+
18
+ protected:
19
+ void control(float value) override;
20
+ bool restore_value_{true};
21
+
22
+ ESPPreferenceObject pref_;
23
+ };
24
+
25
+ } // namespace bl0940
26
+ } // namespace esphome
@@ -8,6 +8,7 @@ from esphome.const import (
8
8
  CONF_ID,
9
9
  CONF_INTERNAL_TEMPERATURE,
10
10
  CONF_POWER,
11
+ CONF_REFERENCE_VOLTAGE,
11
12
  CONF_VOLTAGE,
12
13
  DEVICE_CLASS_CURRENT,
13
14
  DEVICE_CLASS_ENERGY,
@@ -23,12 +24,133 @@ from esphome.const import (
23
24
  UNIT_WATT,
24
25
  )
25
26
 
26
- DEPENDENCIES = ["uart"]
27
+ from . import bl0940_ns
27
28
 
29
+ DEPENDENCIES = ["uart"]
28
30
 
29
- bl0940_ns = cg.esphome_ns.namespace("bl0940")
30
31
  BL0940 = bl0940_ns.class_("BL0940", cg.PollingComponent, uart.UARTDevice)
31
32
 
33
+ CONF_LEGACY_MODE = "legacy_mode"
34
+
35
+ CONF_READ_COMMAND = "read_command"
36
+ CONF_WRITE_COMMAND = "write_command"
37
+
38
+ CONF_RESISTOR_SHUNT = "resistor_shunt"
39
+ CONF_RESISTOR_ONE = "resistor_one"
40
+ CONF_RESISTOR_TWO = "resistor_two"
41
+
42
+ CONF_CURRENT_REFERENCE = "current_reference"
43
+ CONF_ENERGY_REFERENCE = "energy_reference"
44
+ CONF_POWER_REFERENCE = "power_reference"
45
+ CONF_VOLTAGE_REFERENCE = "voltage_reference"
46
+
47
+ DEFAULT_BL0940_READ_COMMAND = 0x58
48
+ DEFAULT_BL0940_WRITE_COMMAND = 0xA1
49
+
50
+ # Values according to BL0940 application note:
51
+ # https://www.belling.com.cn/media/file_object/bel_product/BL0940/guide/BL0940_APPNote_TSSOP14_V1.04_EN.pdf
52
+ DEFAULT_BL0940_VREF = 1.218 # Vref = 1.218
53
+ DEFAULT_BL0940_RL = 1 # RL = 1 mΩ
54
+ DEFAULT_BL0940_R1 = 0.51 # R1 = 0.51 kΩ
55
+ DEFAULT_BL0940_R2 = 1950 # R2 = 5 x 390 kΩ -> 1950 kΩ
56
+
57
+ # ----------------------------------------------------
58
+ # values from initial implementation
59
+ DEFAULT_BL0940_LEGACY_READ_COMMAND = 0x50
60
+ DEFAULT_BL0940_LEGACY_WRITE_COMMAND = 0xA0
61
+
62
+ DEFAULT_BL0940_LEGACY_UREF = 33000
63
+ DEFAULT_BL0940_LEGACY_IREF = 275000
64
+ DEFAULT_BL0940_LEGACY_PREF = 1430
65
+ # Measured to 297J per click according to power consumption of 5 minutes
66
+ # Converted to kWh (3.6MJ per kwH). Used to be 256 * 1638.4
67
+ DEFAULT_BL0940_LEGACY_EREF = 3.6e6 / 297
68
+ # ----------------------------------------------------
69
+
70
+
71
+ # methods to calculate voltage and current reference values
72
+ def calculate_voltage_reference(vref, r_one, r_two):
73
+ # formula: 79931 / Vref * (R1 * 1000) / (R1 + R2)
74
+ return 79931 / vref * (r_one * 1000) / (r_one + r_two)
75
+
76
+
77
+ def calculate_current_reference(vref, r_shunt):
78
+ # formula: 324004 * RL / Vref
79
+ return 324004 * r_shunt / vref
80
+
81
+
82
+ def calculate_power_reference(voltage_reference, current_reference):
83
+ # calculate power reference based on voltage and current reference
84
+ return voltage_reference * current_reference * 4046 / 324004 / 79931
85
+
86
+
87
+ def calculate_energy_reference(power_reference):
88
+ # formula: power_reference * 3600000 / (1638.4 * 256)
89
+ return power_reference * 3600000 / (1638.4 * 256)
90
+
91
+
92
+ def validate_legacy_mode(config):
93
+ # Only allow schematic calibration options if legacy_mode is False
94
+ if config.get(CONF_LEGACY_MODE, True):
95
+ forbidden = [
96
+ CONF_REFERENCE_VOLTAGE,
97
+ CONF_RESISTOR_SHUNT,
98
+ CONF_RESISTOR_ONE,
99
+ CONF_RESISTOR_TWO,
100
+ ]
101
+ for key in forbidden:
102
+ if key in config:
103
+ raise cv.Invalid(
104
+ f"Option '{key}' is only allowed when legacy_mode: false"
105
+ )
106
+ return config
107
+
108
+
109
+ def set_command_defaults(config):
110
+ # Set defaults for read_command and write_command based on legacy_mode
111
+ legacy = config.get(CONF_LEGACY_MODE, True)
112
+ if legacy:
113
+ config.setdefault(CONF_READ_COMMAND, DEFAULT_BL0940_LEGACY_READ_COMMAND)
114
+ config.setdefault(CONF_WRITE_COMMAND, DEFAULT_BL0940_LEGACY_WRITE_COMMAND)
115
+ else:
116
+ config.setdefault(CONF_READ_COMMAND, DEFAULT_BL0940_READ_COMMAND)
117
+ config.setdefault(CONF_WRITE_COMMAND, DEFAULT_BL0940_WRITE_COMMAND)
118
+ return config
119
+
120
+
121
+ def set_reference_values(config):
122
+ # Set default reference values based on legacy_mode
123
+ if config.get(CONF_LEGACY_MODE, True):
124
+ config.setdefault(CONF_VOLTAGE_REFERENCE, DEFAULT_BL0940_LEGACY_UREF)
125
+ config.setdefault(CONF_CURRENT_REFERENCE, DEFAULT_BL0940_LEGACY_IREF)
126
+ config.setdefault(CONF_POWER_REFERENCE, DEFAULT_BL0940_LEGACY_PREF)
127
+ config.setdefault(CONF_ENERGY_REFERENCE, DEFAULT_BL0940_LEGACY_PREF)
128
+ else:
129
+ vref = config.get(CONF_VOLTAGE_REFERENCE, DEFAULT_BL0940_VREF)
130
+ r_one = config.get(CONF_RESISTOR_ONE, DEFAULT_BL0940_R1)
131
+ r_two = config.get(CONF_RESISTOR_TWO, DEFAULT_BL0940_R2)
132
+ r_shunt = config.get(CONF_RESISTOR_SHUNT, DEFAULT_BL0940_RL)
133
+
134
+ config.setdefault(
135
+ CONF_VOLTAGE_REFERENCE, calculate_voltage_reference(vref, r_one, r_two)
136
+ )
137
+ config.setdefault(
138
+ CONF_CURRENT_REFERENCE, calculate_current_reference(vref, r_shunt)
139
+ )
140
+ config.setdefault(
141
+ CONF_POWER_REFERENCE,
142
+ calculate_power_reference(
143
+ config.get(CONF_VOLTAGE_REFERENCE), config.get(CONF_CURRENT_REFERENCE)
144
+ ),
145
+ )
146
+ config.setdefault(
147
+ CONF_ENERGY_REFERENCE,
148
+ calculate_energy_reference(config.get(CONF_POWER_REFERENCE)),
149
+ )
150
+
151
+ return config
152
+
153
+
32
154
  CONFIG_SCHEMA = (
33
155
  cv.Schema(
34
156
  {
@@ -69,10 +191,24 @@ CONFIG_SCHEMA = (
69
191
  device_class=DEVICE_CLASS_TEMPERATURE,
70
192
  state_class=STATE_CLASS_MEASUREMENT,
71
193
  ),
194
+ cv.Optional(CONF_LEGACY_MODE, default=True): cv.boolean,
195
+ cv.Optional(CONF_READ_COMMAND): cv.hex_uint8_t,
196
+ cv.Optional(CONF_WRITE_COMMAND): cv.hex_uint8_t,
197
+ cv.Optional(CONF_REFERENCE_VOLTAGE): cv.float_,
198
+ cv.Optional(CONF_RESISTOR_SHUNT): cv.float_,
199
+ cv.Optional(CONF_RESISTOR_ONE): cv.float_,
200
+ cv.Optional(CONF_RESISTOR_TWO): cv.float_,
201
+ cv.Optional(CONF_CURRENT_REFERENCE): cv.float_,
202
+ cv.Optional(CONF_ENERGY_REFERENCE): cv.float_,
203
+ cv.Optional(CONF_POWER_REFERENCE): cv.float_,
204
+ cv.Optional(CONF_VOLTAGE_REFERENCE): cv.float_,
72
205
  }
73
206
  )
74
207
  .extend(cv.polling_component_schema("60s"))
75
208
  .extend(uart.UART_DEVICE_SCHEMA)
209
+ .add_extra(validate_legacy_mode)
210
+ .add_extra(set_command_defaults)
211
+ .add_extra(set_reference_values)
76
212
  )
77
213
 
78
214
 
@@ -99,3 +235,16 @@ async def to_code(config):
99
235
  if external_temperature_config := config.get(CONF_EXTERNAL_TEMPERATURE):
100
236
  sens = await sensor.new_sensor(external_temperature_config)
101
237
  cg.add(var.set_external_temperature_sensor(sens))
238
+
239
+ # enable legacy mode
240
+ cg.add(var.set_legacy_mode(config.get(CONF_LEGACY_MODE)))
241
+
242
+ # Set bl0940 commands after validator has determined which defaults to use if not set
243
+ cg.add(var.set_read_command(config.get(CONF_READ_COMMAND)))
244
+ cg.add(var.set_write_command(config.get(CONF_WRITE_COMMAND)))
245
+
246
+ # Set reference values after validator has set the values either from defaults or calculated
247
+ cg.add(var.set_current_reference(config.get(CONF_CURRENT_REFERENCE)))
248
+ cg.add(var.set_voltage_reference(config.get(CONF_VOLTAGE_REFERENCE)))
249
+ cg.add(var.set_power_reference(config.get(CONF_POWER_REFERENCE)))
250
+ cg.add(var.set_energy_reference(config.get(CONF_ENERGY_REFERENCE)))
@@ -149,7 +149,7 @@ void BL0942::setup() {
149
149
  this->write_reg_(BL0942_REG_USR_WRPROT, 0);
150
150
 
151
151
  if (this->read_reg_(BL0942_REG_MODE) != mode)
152
- this->status_set_warning("BL0942 setup failed!");
152
+ this->status_set_warning(LOG_STR("BL0942 setup failed!"));
153
153
 
154
154
  this->flush();
155
155
  }
@@ -27,7 +27,7 @@ CONFIG_SCHEMA = cv.All(
27
27
  )
28
28
 
29
29
 
30
- def to_code(config):
30
+ async def to_code(config):
31
31
  var = cg.new_Pvariable(config[CONF_ID])
32
32
  if len(config[CONF_SERVICE_UUID]) == len(esp32_ble_tracker.bt_uuid16_format):
33
33
  cg.add(
@@ -63,6 +63,6 @@ def to_code(config):
63
63
  )
64
64
  cg.add(var.set_char_uuid128(uuid128))
65
65
  cg.add(var.set_require_response(config[CONF_REQUIRE_RESPONSE]))
66
- yield output.register_output(var, config)
67
- yield ble_client.register_ble_node(var, config)
68
- yield cg.register_component(var, config)
66
+ await output.register_output(var, config)
67
+ await ble_client.register_ble_node(var, config)
68
+ await cg.register_component(var, config)
@@ -80,7 +80,7 @@ CONFIG_SCHEMA = cv.All(
80
80
  cv.Schema(
81
81
  {
82
82
  cv.GenerateID(): cv.declare_id(BluetoothProxy),
83
- cv.Optional(CONF_ACTIVE, default=False): cv.boolean,
83
+ cv.Optional(CONF_ACTIVE, default=True): cv.boolean,
84
84
  cv.SplitDefault(CONF_CACHE_SERVICES, esp32_idf=True): cv.All(
85
85
  cv.only_with_esp_idf, cv.boolean
86
86
  ),