esphome 2024.8.2__py3-none-any.whl → 2024.9.0__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 (204) hide show
  1. esphome/__main__.py +6 -2
  2. esphome/components/api/api_connection.cpp +53 -0
  3. esphome/components/api/api_connection.h +4 -0
  4. esphome/components/api/api_pb2.cpp +280 -0
  5. esphome/components/api/api_pb2.h +91 -0
  6. esphome/components/api/api_pb2_service.cpp +85 -0
  7. esphome/components/api/api_pb2_service.h +28 -0
  8. esphome/components/async_tcp/__init__.py +3 -3
  9. esphome/components/atm90e26/sensor.py +10 -10
  10. esphome/components/atm90e32/sensor.py +1 -1
  11. esphome/components/bl0906/__init__.py +1 -0
  12. esphome/components/bl0906/bl0906.cpp +238 -0
  13. esphome/components/bl0906/bl0906.h +96 -0
  14. esphome/components/bl0906/const.py +4 -0
  15. esphome/components/bl0906/constants.h +122 -0
  16. esphome/components/bl0906/sensor.py +184 -0
  17. esphome/components/bl0942/__init__.py +1 -1
  18. esphome/components/bl0942/bl0942.cpp +127 -34
  19. esphome/components/bl0942/bl0942.h +87 -3
  20. esphome/components/bl0942/sensor.py +46 -8
  21. esphome/components/ble_client/__init__.py +1 -3
  22. esphome/components/ble_presence/binary_sensor.py +2 -2
  23. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +5 -0
  24. esphome/components/bmp280/sensor.py +2 -93
  25. esphome/components/bmp280_base/__init__.py +88 -0
  26. esphome/components/{bmp280/bmp280.cpp → bmp280_base/bmp280_base.cpp} +11 -4
  27. esphome/components/{bmp280/bmp280.h → bmp280_base/bmp280_base.h} +9 -5
  28. esphome/components/bmp280_i2c/__init__.py +0 -0
  29. esphome/components/bmp280_i2c/bmp280_i2c.cpp +27 -0
  30. esphome/components/bmp280_i2c/bmp280_i2c.h +22 -0
  31. esphome/components/bmp280_i2c/sensor.py +22 -0
  32. esphome/components/bmp280_spi/__init__.py +0 -0
  33. esphome/components/bmp280_spi/bmp280_spi.cpp +65 -0
  34. esphome/components/bmp280_spi/bmp280_spi.h +20 -0
  35. esphome/components/bmp280_spi/sensor.py +22 -0
  36. esphome/components/captive_portal/captive_portal.cpp +2 -0
  37. esphome/components/captive_portal/captive_portal.h +3 -1
  38. esphome/components/ch422g/__init__.py +67 -0
  39. esphome/components/ch422g/ch422g.cpp +122 -0
  40. esphome/components/ch422g/ch422g.h +70 -0
  41. esphome/components/debug/debug_esp32.cpp +3 -1
  42. esphome/components/display/__init__.py +5 -4
  43. esphome/components/dsmr/dsmr.cpp +6 -0
  44. esphome/components/dsmr/dsmr.h +6 -0
  45. esphome/components/dsmr/text_sensor.py +7 -2
  46. esphome/components/e131/e131.cpp +2 -0
  47. esphome/components/e131/e131.h +3 -1
  48. esphome/components/e131/e131_addressable_light_effect.cpp +2 -0
  49. esphome/components/e131/e131_addressable_light_effect.h +2 -1
  50. esphome/components/e131/e131_packet.cpp +2 -0
  51. esphome/components/esp32_ble/ble_uuid.cpp +7 -0
  52. esphome/components/esp32_ble/ble_uuid.h +1 -0
  53. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +11 -9
  54. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +3 -3
  55. esphome/components/esp32_camera/__init__.py +4 -0
  56. esphome/components/esp32_camera/esp32_camera.cpp +9 -1
  57. esphome/components/esp32_camera/esp32_camera.h +3 -0
  58. esphome/components/esp32_can/canbus.py +18 -7
  59. esphome/components/esp32_can/esp32_can.cpp +8 -0
  60. esphome/components/esp32_can/esp32_can.h +4 -0
  61. esphome/components/esp32_rmt_led_strip/led_strip.cpp +14 -2
  62. esphome/components/esp32_rmt_led_strip/led_strip.h +3 -2
  63. esphome/components/esp32_rmt_led_strip/light.py +21 -4
  64. esphome/components/esphome/ota/ota_esphome.cpp +2 -1
  65. esphome/components/esphome/ota/ota_esphome.h +2 -0
  66. esphome/components/font/__init__.py +11 -22
  67. esphome/components/font/font.cpp +3 -2
  68. esphome/components/font/font.h +12 -3
  69. esphome/components/gree/climate.py +2 -1
  70. esphome/components/gree/gree.cpp +54 -3
  71. esphome/components/gree/gree.h +10 -2
  72. esphome/components/gt911/touchscreen/__init__.py +6 -4
  73. esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +17 -0
  74. esphome/components/gt911/touchscreen/gt911_touchscreen.h +2 -0
  75. esphome/components/hmac_md5/__init__.py +2 -0
  76. esphome/components/hmac_md5/hmac_md5.cpp +56 -0
  77. esphome/components/hmac_md5/hmac_md5.h +48 -0
  78. esphome/components/homeassistant/__init__.py +13 -0
  79. esphome/components/homeassistant/switch/__init__.py +15 -2
  80. esphome/components/homeassistant/switch/homeassistant_switch.cpp +2 -2
  81. esphome/components/i2s_audio/__init__.py +88 -9
  82. esphome/components/i2s_audio/i2s_audio.h +20 -2
  83. esphome/components/i2s_audio/media_player/__init__.py +8 -4
  84. esphome/components/i2s_audio/media_player/i2s_audio_media_player.h +1 -1
  85. esphome/components/i2s_audio/microphone/__init__.py +19 -51
  86. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +18 -15
  87. esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +0 -12
  88. esphome/components/i2s_audio/speaker/__init__.py +39 -27
  89. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +49 -37
  90. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +3 -4
  91. esphome/components/ili9xxx/display.py +16 -17
  92. esphome/components/ili9xxx/ili9xxx_display.cpp +1 -1
  93. esphome/components/ili9xxx/ili9xxx_display.h +18 -18
  94. esphome/components/ili9xxx/ili9xxx_init.h +0 -3
  95. esphome/components/improv_serial/improv_serial_component.cpp +2 -1
  96. esphome/components/improv_serial/improv_serial_component.h +2 -1
  97. esphome/components/ledc/ledc_output.cpp +11 -7
  98. esphome/components/libretiny/__init__.py +8 -13
  99. esphome/components/ltr501/__init__.py +1 -0
  100. esphome/components/ltr501/ltr501.cpp +542 -0
  101. esphome/components/ltr501/ltr501.h +184 -0
  102. esphome/components/ltr501/ltr_definitions_501.h +260 -0
  103. esphome/components/ltr501/sensor.py +274 -0
  104. esphome/components/ltr_als_ps/sensor.py +2 -2
  105. esphome/components/lvgl/__init__.py +19 -16
  106. esphome/components/lvgl/automation.py +90 -9
  107. esphome/components/lvgl/defines.py +29 -2
  108. esphome/components/lvgl/gradient.py +61 -0
  109. esphome/components/lvgl/lv_validation.py +45 -27
  110. esphome/components/lvgl/lvcode.py +8 -3
  111. esphome/components/lvgl/lvgl_esphome.cpp +54 -0
  112. esphome/components/lvgl/lvgl_esphome.h +9 -3
  113. esphome/components/lvgl/number/__init__.py +1 -0
  114. esphome/components/lvgl/number/lvgl_number.h +3 -1
  115. esphome/components/lvgl/schemas.py +16 -11
  116. esphome/components/lvgl/select/__init__.py +1 -0
  117. esphome/components/lvgl/select/lvgl_select.h +3 -1
  118. esphome/components/lvgl/switch/__init__.py +2 -1
  119. esphome/components/lvgl/switch/lvgl_switch.h +3 -1
  120. esphome/components/lvgl/text/__init__.py +1 -0
  121. esphome/components/lvgl/text/lvgl_text.h +3 -1
  122. esphome/components/lvgl/trigger.py +3 -2
  123. esphome/components/lvgl/types.py +2 -1
  124. esphome/components/lvgl/widgets/__init__.py +23 -8
  125. esphome/components/lvgl/widgets/arc.py +5 -1
  126. esphome/components/lvgl/widgets/buttonmatrix.py +5 -1
  127. esphome/components/lvgl/widgets/checkbox.py +8 -3
  128. esphome/components/lvgl/widgets/meter.py +8 -1
  129. esphome/components/lvgl/widgets/msgbox.py +26 -15
  130. esphome/components/lvgl/widgets/page.py +51 -7
  131. esphome/components/lvgl/widgets/tileview.py +2 -8
  132. esphome/components/max31856/max31856.cpp +12 -1
  133. esphome/components/max31856/max31856.h +5 -2
  134. esphome/components/max31856/sensor.py +20 -0
  135. esphome/components/mcp9600/sensor.py +2 -2
  136. esphome/components/mdns/__init__.py +6 -6
  137. esphome/components/media_player/media_player.h +16 -0
  138. esphome/components/micro_wake_word/__init__.py +2 -25
  139. esphome/components/microphone/microphone.h +1 -1
  140. esphome/components/mics_4514/mics_4514.cpp +26 -36
  141. esphome/components/modbus_controller/__init__.py +6 -0
  142. esphome/components/modbus_controller/const.py +2 -0
  143. esphome/components/modbus_controller/modbus_controller.cpp +30 -27
  144. esphome/components/modbus_controller/modbus_controller.h +22 -4
  145. esphome/components/network/__init__.py +11 -8
  146. esphome/components/pipsolar/pipsolar.cpp +3 -0
  147. esphome/components/pipsolar/pipsolar.h +1 -0
  148. esphome/components/pipsolar/switch/__init__.py +2 -0
  149. esphome/components/prometheus/prometheus_handler.cpp +2 -0
  150. esphome/components/prometheus/prometheus_handler.h +3 -1
  151. esphome/components/rp2040/__init__.py +7 -8
  152. esphome/components/rpi_dpi_rgb/display.py +20 -17
  153. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +36 -6
  154. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.h +4 -0
  155. esphome/components/socket/socket.cpp +2 -0
  156. esphome/components/socket/socket.h +2 -0
  157. esphome/components/speaker/speaker.h +1 -1
  158. esphome/components/st7701s/display.py +35 -37
  159. esphome/components/st7701s/st7701s.cpp +11 -6
  160. esphome/components/st7701s/st7701s.h +1 -0
  161. esphome/components/statsd/__init__.py +65 -0
  162. esphome/components/statsd/statsd.cpp +156 -0
  163. esphome/components/statsd/statsd.h +86 -0
  164. esphome/components/tuya/__init__.py +1 -0
  165. esphome/components/tuya/number/__init__.py +39 -2
  166. esphome/components/tuya/number/tuya_number.cpp +58 -2
  167. esphome/components/tuya/number/tuya_number.h +12 -3
  168. esphome/components/udp/__init__.py +158 -0
  169. esphome/components/udp/binary_sensor.py +27 -0
  170. esphome/components/udp/sensor.py +27 -0
  171. esphome/components/udp/udp_component.cpp +616 -0
  172. esphome/components/udp/udp_component.h +158 -0
  173. esphome/components/uponor_smatrix/uponor_smatrix.cpp +4 -6
  174. esphome/components/uponor_smatrix/uponor_smatrix.h +0 -1
  175. esphome/components/veml7700/sensor.py +2 -2
  176. esphome/components/voice_assistant/__init__.py +6 -0
  177. esphome/components/voice_assistant/voice_assistant.cpp +24 -2
  178. esphome/components/voice_assistant/voice_assistant.h +20 -0
  179. esphome/components/web_server/__init__.py +11 -11
  180. esphome/components/web_server/list_entities.cpp +2 -0
  181. esphome/components/web_server/list_entities.h +3 -1
  182. esphome/components/web_server/web_server.cpp +2 -1
  183. esphome/components/web_server/web_server.h +2 -0
  184. esphome/components/web_server_base/web_server_base.cpp +2 -0
  185. esphome/components/web_server_base/web_server_base.h +3 -1
  186. esphome/components/wifi/wifi_component_libretiny.cpp +15 -1
  187. esphome/components/wireguard/__init__.py +9 -6
  188. esphome/components/wireguard/wireguard.cpp +2 -1
  189. esphome/components/wireguard/wireguard.h +3 -1
  190. esphome/config_validation.py +8 -0
  191. esphome/const.py +8 -1
  192. esphome/core/bytebuffer.cpp +117 -84
  193. esphome/core/bytebuffer.h +69 -21
  194. esphome/core/config.py +0 -3
  195. esphome/core/defines.h +2 -0
  196. esphome/core/ring_buffer.cpp +13 -2
  197. esphome/core/ring_buffer.h +56 -0
  198. esphome/external_files.py +5 -3
  199. {esphome-2024.8.2.dist-info → esphome-2024.9.0.dist-info}/METADATA +1 -1
  200. {esphome-2024.8.2.dist-info → esphome-2024.9.0.dist-info}/RECORD +204 -169
  201. {esphome-2024.8.2.dist-info → esphome-2024.9.0.dist-info}/LICENSE +0 -0
  202. {esphome-2024.8.2.dist-info → esphome-2024.9.0.dist-info}/WHEEL +0 -0
  203. {esphome-2024.8.2.dist-info → esphome-2024.9.0.dist-info}/entry_points.txt +0 -0
  204. {esphome-2024.8.2.dist-info → esphome-2024.9.0.dist-info}/top_level.txt +0 -0
@@ -1,13 +1,13 @@
1
1
  # Dummy integration to allow relying on AsyncTCP
2
2
  import esphome.codegen as cg
3
3
  import esphome.config_validation as cv
4
- from esphome.core import CORE, coroutine_with_priority
5
4
  from esphome.const import (
5
+ PLATFORM_BK72XX,
6
6
  PLATFORM_ESP32,
7
7
  PLATFORM_ESP8266,
8
- PLATFORM_BK72XX,
9
8
  PLATFORM_RTL87XX,
10
9
  )
10
+ from esphome.core import CORE, coroutine_with_priority
11
11
 
12
12
  CODEOWNERS = ["@OttoWinter"]
13
13
 
@@ -22,7 +22,7 @@ CONFIG_SCHEMA = cv.All(
22
22
  async def to_code(config):
23
23
  if CORE.is_esp32 or CORE.is_libretiny:
24
24
  # https://github.com/esphome/AsyncTCP/blob/master/library.json
25
- cg.add_library("esphome/AsyncTCP-esphome", "2.1.3")
25
+ cg.add_library("esphome/AsyncTCP-esphome", "2.1.4")
26
26
  elif CORE.is_esp8266:
27
27
  # https://github.com/esphome/ESPAsyncTCP
28
28
  cg.add_library("esphome/ESPAsyncTCP-esphome", "2.0.0")
@@ -1,34 +1,34 @@
1
1
  import esphome.codegen as cg
2
- import esphome.config_validation as cv
3
2
  from esphome.components import sensor, spi
3
+ import esphome.config_validation as cv
4
4
  from esphome.const import (
5
- CONF_ID,
6
- CONF_REACTIVE_POWER,
7
- CONF_VOLTAGE,
8
5
  CONF_CURRENT,
6
+ CONF_FORWARD_ACTIVE_ENERGY,
7
+ CONF_FREQUENCY,
8
+ CONF_ID,
9
+ CONF_LINE_FREQUENCY,
9
10
  CONF_POWER,
10
11
  CONF_POWER_FACTOR,
11
- CONF_FREQUENCY,
12
- CONF_FORWARD_ACTIVE_ENERGY,
12
+ CONF_REACTIVE_POWER,
13
13
  CONF_REVERSE_ACTIVE_ENERGY,
14
+ CONF_VOLTAGE,
14
15
  DEVICE_CLASS_CURRENT,
15
16
  DEVICE_CLASS_ENERGY,
16
17
  DEVICE_CLASS_POWER,
17
18
  DEVICE_CLASS_POWER_FACTOR,
18
19
  DEVICE_CLASS_VOLTAGE,
19
- ICON_LIGHTBULB,
20
20
  ICON_CURRENT_AC,
21
+ ICON_LIGHTBULB,
21
22
  STATE_CLASS_MEASUREMENT,
22
23
  STATE_CLASS_TOTAL_INCREASING,
24
+ UNIT_AMPERE,
23
25
  UNIT_HERTZ,
24
26
  UNIT_VOLT,
25
- UNIT_AMPERE,
26
- UNIT_WATT,
27
27
  UNIT_VOLT_AMPS_REACTIVE,
28
+ UNIT_WATT,
28
29
  UNIT_WATT_HOURS,
29
30
  )
30
31
 
31
- CONF_LINE_FREQUENCY = "line_frequency"
32
32
  CONF_METER_CONSTANT = "meter_constant"
33
33
  CONF_PL_CONST = "pl_const"
34
34
  CONF_GAIN_PGA = "gain_pga"
@@ -7,6 +7,7 @@ from esphome.const import (
7
7
  CONF_FORWARD_ACTIVE_ENERGY,
8
8
  CONF_FREQUENCY,
9
9
  CONF_ID,
10
+ CONF_LINE_FREQUENCY,
10
11
  CONF_PHASE_A,
11
12
  CONF_PHASE_ANGLE,
12
13
  CONF_PHASE_B,
@@ -39,7 +40,6 @@ from esphome.const import (
39
40
 
40
41
  from . import atm90e32_ns
41
42
 
42
- CONF_LINE_FREQUENCY = "line_frequency"
43
43
  CONF_CHIP_TEMPERATURE = "chip_temperature"
44
44
  CONF_GAIN_PGA = "gain_pga"
45
45
  CONF_CURRENT_PHASES = "current_phases"
@@ -0,0 +1 @@
1
+ CODEOWNERS = ["@athom-tech", "@tarontop", "@jesserockz"]
@@ -0,0 +1,238 @@
1
+ #include "bl0906.h"
2
+ #include "constants.h"
3
+
4
+ #include "esphome/core/log.h"
5
+
6
+ namespace esphome {
7
+ namespace bl0906 {
8
+
9
+ static const char *const TAG = "bl0906";
10
+
11
+ constexpr uint32_t to_uint32_t(ube24_t input) { return input.h << 16 | input.m << 8 | input.l; }
12
+
13
+ constexpr int32_t to_int32_t(sbe24_t input) { return input.h << 16 | input.m << 8 | input.l; }
14
+
15
+ // The SUM byte is (Addr+Data_L+Data_M+Data_H)&0xFF negated;
16
+ constexpr uint8_t bl0906_checksum(const uint8_t address, const DataPacket *data) {
17
+ return (address + data->l + data->m + data->h) ^ 0xFF;
18
+ }
19
+
20
+ void BL0906::loop() {
21
+ if (this->current_channel_ == UINT8_MAX) {
22
+ return;
23
+ }
24
+
25
+ while (this->available())
26
+ this->flush();
27
+
28
+ if (this->current_channel_ == 0) {
29
+ // Temperature
30
+ this->read_data_(BL0906_TEMPERATURE, BL0906_TREF, this->temperature_sensor_);
31
+ } else if (this->current_channel_ == 1) {
32
+ this->read_data_(BL0906_I_1_RMS, BL0906_IREF, this->current_1_sensor_);
33
+ this->read_data_(BL0906_WATT_1, BL0906_PREF, this->power_1_sensor_);
34
+ this->read_data_(BL0906_CF_1_CNT, BL0906_EREF, this->energy_1_sensor_);
35
+ } else if (this->current_channel_ == 2) {
36
+ this->read_data_(BL0906_I_2_RMS, BL0906_IREF, this->current_2_sensor_);
37
+ this->read_data_(BL0906_WATT_2, BL0906_PREF, this->power_2_sensor_);
38
+ this->read_data_(BL0906_CF_2_CNT, BL0906_EREF, this->energy_2_sensor_);
39
+ } else if (this->current_channel_ == 3) {
40
+ this->read_data_(BL0906_I_3_RMS, BL0906_IREF, this->current_3_sensor_);
41
+ this->read_data_(BL0906_WATT_3, BL0906_PREF, this->power_3_sensor_);
42
+ this->read_data_(BL0906_CF_3_CNT, BL0906_EREF, this->energy_3_sensor_);
43
+ } else if (this->current_channel_ == 4) {
44
+ this->read_data_(BL0906_I_4_RMS, BL0906_IREF, this->current_4_sensor_);
45
+ this->read_data_(BL0906_WATT_4, BL0906_PREF, this->power_4_sensor_);
46
+ this->read_data_(BL0906_CF_4_CNT, BL0906_EREF, this->energy_4_sensor_);
47
+ } else if (this->current_channel_ == 5) {
48
+ this->read_data_(BL0906_I_5_RMS, BL0906_IREF, this->current_5_sensor_);
49
+ this->read_data_(BL0906_WATT_5, BL0906_PREF, this->power_5_sensor_);
50
+ this->read_data_(BL0906_CF_5_CNT, BL0906_EREF, this->energy_5_sensor_);
51
+ } else if (this->current_channel_ == 6) {
52
+ this->read_data_(BL0906_I_6_RMS, BL0906_IREF, this->current_6_sensor_);
53
+ this->read_data_(BL0906_WATT_6, BL0906_PREF, this->power_6_sensor_);
54
+ this->read_data_(BL0906_CF_6_CNT, BL0906_EREF, this->energy_6_sensor_);
55
+ } else if (this->current_channel_ == UINT8_MAX - 2) {
56
+ // Frequency
57
+ this->read_data_(BL0906_FREQUENCY, BL0906_FREF, frequency_sensor_);
58
+ // Voltage
59
+ this->read_data_(BL0906_V_RMS, BL0906_UREF, voltage_sensor_);
60
+ } else if (this->current_channel_ == UINT8_MAX - 1) {
61
+ // Total power
62
+ this->read_data_(BL0906_WATT_SUM, BL0906_WATT, this->total_power_sensor_);
63
+ // Total Energy
64
+ this->read_data_(BL0906_CF_SUM_CNT, BL0906_CF, this->total_energy_sensor_);
65
+ } else {
66
+ this->current_channel_ = UINT8_MAX - 2; // Go to frequency and voltage
67
+ return;
68
+ }
69
+ this->current_channel_++;
70
+ this->handle_actions_();
71
+ }
72
+
73
+ void BL0906::setup() {
74
+ while (this->available())
75
+ this->flush();
76
+ this->write_array(USR_WRPROT_WITABLE, sizeof(USR_WRPROT_WITABLE));
77
+ // Calibration (1: register address; 2: value before calibration; 3: value after calibration)
78
+ this->bias_correction_(BL0906_RMSOS_1, 0.01600, 0); // Calibration current_1
79
+ this->bias_correction_(BL0906_RMSOS_2, 0.01500, 0);
80
+ this->bias_correction_(BL0906_RMSOS_3, 0.01400, 0);
81
+ this->bias_correction_(BL0906_RMSOS_4, 0.01300, 0);
82
+ this->bias_correction_(BL0906_RMSOS_5, 0.01200, 0);
83
+ this->bias_correction_(BL0906_RMSOS_6, 0.01200, 0); // Calibration current_6
84
+
85
+ this->write_array(USR_WRPROT_ONLYREAD, sizeof(USR_WRPROT_ONLYREAD));
86
+ }
87
+
88
+ void BL0906::update() { this->current_channel_ = 0; }
89
+
90
+ size_t BL0906::enqueue_action_(ActionCallbackFuncPtr function) {
91
+ this->action_queue_.push_back(function);
92
+ return this->action_queue_.size();
93
+ }
94
+
95
+ void BL0906::handle_actions_() {
96
+ if (this->action_queue_.empty()) {
97
+ return;
98
+ }
99
+ ActionCallbackFuncPtr ptr_func = nullptr;
100
+ for (int i = 0; i < this->action_queue_.size(); i++) {
101
+ ptr_func = this->action_queue_[i];
102
+ if (ptr_func) {
103
+ ESP_LOGI(TAG, "HandleActionCallback[%d]...", i);
104
+ (this->*ptr_func)();
105
+ }
106
+ }
107
+
108
+ while (this->available()) {
109
+ this->read();
110
+ }
111
+
112
+ this->action_queue_.clear();
113
+ }
114
+
115
+ // Reset energy
116
+ void BL0906::reset_energy_() {
117
+ this->write_array(BL0906_INIT[0], 6);
118
+ delay(1);
119
+ this->flush();
120
+
121
+ ESP_LOGW(TAG, "RMSOS:%02X%02X%02X%02X%02X%02X", BL0906_INIT[0][0], BL0906_INIT[0][1], BL0906_INIT[0][2],
122
+ BL0906_INIT[0][3], BL0906_INIT[0][4], BL0906_INIT[0][5]);
123
+ }
124
+
125
+ // Read data
126
+ void BL0906::read_data_(const uint8_t address, const float reference, sensor::Sensor *sensor) {
127
+ if (sensor == nullptr) {
128
+ return;
129
+ }
130
+ DataPacket buffer;
131
+ ube24_t data_u24;
132
+ sbe24_t data_s24;
133
+ float value = 0;
134
+
135
+ bool signed_result = reference == BL0906_TREF || reference == BL0906_WATT || reference == BL0906_PREF;
136
+
137
+ this->write_byte(BL0906_READ_COMMAND);
138
+ this->write_byte(address);
139
+ if (this->read_array((uint8_t *) &buffer, sizeof(buffer) - 1)) {
140
+ if (bl0906_checksum(address, &buffer) == buffer.checksum) {
141
+ if (signed_result) {
142
+ data_s24.l = buffer.l;
143
+ data_s24.m = buffer.m;
144
+ data_s24.h = buffer.h;
145
+ } else {
146
+ data_u24.l = buffer.l;
147
+ data_u24.m = buffer.m;
148
+ data_u24.h = buffer.h;
149
+ }
150
+ } else {
151
+ ESP_LOGW(TAG, "Junk on wire. Throwing away partial message");
152
+ while (read() >= 0)
153
+ ;
154
+ return;
155
+ }
156
+ }
157
+ // Power
158
+ if (reference == BL0906_PREF) {
159
+ value = (float) to_int32_t(data_s24) * reference;
160
+ }
161
+
162
+ // Total power
163
+ if (reference == BL0906_WATT) {
164
+ value = (float) to_int32_t(data_s24) * reference;
165
+ }
166
+
167
+ // Voltage, current, power, total power
168
+ if (reference == BL0906_UREF || reference == BL0906_IREF || reference == BL0906_EREF || reference == BL0906_CF) {
169
+ value = (float) to_uint32_t(data_u24) * reference;
170
+ }
171
+
172
+ // Frequency
173
+ if (reference == BL0906_FREF) {
174
+ value = reference / (float) to_uint32_t(data_u24);
175
+ }
176
+ // Chip temperature
177
+ if (reference == BL0906_TREF) {
178
+ value = (float) to_int32_t(data_s24);
179
+ value = (value - 64) * 12.5 / 59 - 40;
180
+ }
181
+ sensor->publish_state(value);
182
+ }
183
+
184
+ // RMS offset correction
185
+ void BL0906::bias_correction_(uint8_t address, float measurements, float correction) {
186
+ DataPacket data;
187
+ float ki = 12875 * 1 * (5.1 + 5.1) * 1000 / 2000 / 1.097; // Current coefficient
188
+ float i_rms0 = measurements * ki;
189
+ float i_rms = correction * ki;
190
+ int32_t value = (i_rms * i_rms - i_rms0 * i_rms0) / 256;
191
+ data.l = value << 24 >> 24;
192
+ data.m = value << 16 >> 24;
193
+ if (value < 0) {
194
+ data.h = (value << 8 >> 24) | 0b10000000;
195
+ }
196
+ data.address = bl0906_checksum(address, &data);
197
+ ESP_LOGV(TAG, "RMSOS:%02X%02X%02X%02X%02X%02X", BL0906_WRITE_COMMAND, address, data.l, data.m, data.h, data.address);
198
+ this->write_byte(BL0906_WRITE_COMMAND);
199
+ this->write_byte(address);
200
+ this->write_byte(data.l);
201
+ this->write_byte(data.m);
202
+ this->write_byte(data.h);
203
+ this->write_byte(data.address);
204
+ }
205
+
206
+ void BL0906::dump_config() {
207
+ ESP_LOGCONFIG(TAG, "BL0906:");
208
+ LOG_SENSOR(" ", "Voltage", this->voltage_sensor_);
209
+
210
+ LOG_SENSOR(" ", "Current1", this->current_1_sensor_);
211
+ LOG_SENSOR(" ", "Current2", this->current_2_sensor_);
212
+ LOG_SENSOR(" ", "Current3", this->current_3_sensor_);
213
+ LOG_SENSOR(" ", "Current4", this->current_4_sensor_);
214
+ LOG_SENSOR(" ", "Current5", this->current_5_sensor_);
215
+ LOG_SENSOR(" ", "Current6", this->current_6_sensor_);
216
+
217
+ LOG_SENSOR(" ", "Power1", this->power_1_sensor_);
218
+ LOG_SENSOR(" ", "Power2", this->power_2_sensor_);
219
+ LOG_SENSOR(" ", "Power3", this->power_3_sensor_);
220
+ LOG_SENSOR(" ", "Power4", this->power_4_sensor_);
221
+ LOG_SENSOR(" ", "Power5", this->power_5_sensor_);
222
+ LOG_SENSOR(" ", "Power6", this->power_6_sensor_);
223
+
224
+ LOG_SENSOR(" ", "Energy1", this->energy_1_sensor_);
225
+ LOG_SENSOR(" ", "Energy2", this->energy_2_sensor_);
226
+ LOG_SENSOR(" ", "Energy3", this->energy_3_sensor_);
227
+ LOG_SENSOR(" ", "Energy4", this->energy_4_sensor_);
228
+ LOG_SENSOR(" ", "Energy5", this->energy_5_sensor_);
229
+ LOG_SENSOR(" ", "Energy6", this->energy_6_sensor_);
230
+
231
+ LOG_SENSOR(" ", "Total Power", this->total_power_sensor_);
232
+ LOG_SENSOR(" ", "Total Energy", this->total_energy_sensor_);
233
+ LOG_SENSOR(" ", "Frequency", this->frequency_sensor_);
234
+ LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
235
+ }
236
+
237
+ } // namespace bl0906
238
+ } // namespace esphome
@@ -0,0 +1,96 @@
1
+ #pragma once
2
+
3
+ #include "esphome/components/sensor/sensor.h"
4
+ #include "esphome/components/uart/uart.h"
5
+ #include "esphome/core/automation.h"
6
+ #include "esphome/core/component.h"
7
+ #include "esphome/core/datatypes.h"
8
+
9
+ // https://www.belling.com.cn/media/file_object/bel_product/BL0906/datasheet/BL0906_V1.02_cn.pdf
10
+ // https://www.belling.com.cn/media/file_object/bel_product/BL0906/guide/BL0906%20APP%20Note_V1.02.pdf
11
+
12
+ namespace esphome {
13
+ namespace bl0906 {
14
+
15
+ struct DataPacket { // NOLINT(altera-struct-pack-align)
16
+ uint8_t l{0};
17
+ uint8_t m{0};
18
+ uint8_t h{0};
19
+ uint8_t checksum; // checksum
20
+ uint8_t address;
21
+ } __attribute__((packed));
22
+
23
+ struct ube24_t { // NOLINT(readability-identifier-naming,altera-struct-pack-align)
24
+ uint8_t l{0};
25
+ uint8_t m{0};
26
+ uint8_t h{0};
27
+ } __attribute__((packed));
28
+
29
+ struct sbe24_t { // NOLINT(readability-identifier-naming,altera-struct-pack-align)
30
+ uint8_t l{0};
31
+ uint8_t m{0};
32
+ int8_t h{0};
33
+ } __attribute__((packed));
34
+
35
+ template<typename... Ts> class ResetEnergyAction;
36
+
37
+ class BL0906;
38
+
39
+ using ActionCallbackFuncPtr = void (BL0906::*)();
40
+
41
+ class BL0906 : public PollingComponent, public uart::UARTDevice {
42
+ SUB_SENSOR(voltage)
43
+ SUB_SENSOR(current_1)
44
+ SUB_SENSOR(current_2)
45
+ SUB_SENSOR(current_3)
46
+ SUB_SENSOR(current_4)
47
+ SUB_SENSOR(current_5)
48
+ SUB_SENSOR(current_6)
49
+ SUB_SENSOR(power_1)
50
+ SUB_SENSOR(power_2)
51
+ SUB_SENSOR(power_3)
52
+ SUB_SENSOR(power_4)
53
+ SUB_SENSOR(power_5)
54
+ SUB_SENSOR(power_6)
55
+ SUB_SENSOR(total_power)
56
+ SUB_SENSOR(energy_1)
57
+ SUB_SENSOR(energy_2)
58
+ SUB_SENSOR(energy_3)
59
+ SUB_SENSOR(energy_4)
60
+ SUB_SENSOR(energy_5)
61
+ SUB_SENSOR(energy_6)
62
+ SUB_SENSOR(total_energy)
63
+ SUB_SENSOR(frequency)
64
+ SUB_SENSOR(temperature)
65
+
66
+ public:
67
+ void loop() override;
68
+
69
+ void update() override;
70
+ void setup() override;
71
+ void dump_config() override;
72
+
73
+ protected:
74
+ template<typename... Ts> friend class ResetEnergyAction;
75
+
76
+ void reset_energy_();
77
+
78
+ void read_data_(uint8_t address, float reference, sensor::Sensor *sensor);
79
+
80
+ void bias_correction_(uint8_t address, float measurements, float correction);
81
+
82
+ uint8_t current_channel_{0};
83
+ size_t enqueue_action_(ActionCallbackFuncPtr function);
84
+ void handle_actions_();
85
+
86
+ private:
87
+ std::vector<ActionCallbackFuncPtr> action_queue_{};
88
+ };
89
+
90
+ template<typename... Ts> class ResetEnergyAction : public Action<Ts...>, public Parented<BL0906> {
91
+ public:
92
+ void play(Ts... x) override { this->parent_->enqueue_action_(&BL0906::reset_energy_); }
93
+ };
94
+
95
+ } // namespace bl0906
96
+ } // namespace esphome
@@ -0,0 +1,4 @@
1
+ # const.py
2
+ ICON_ENERGY = "mdi:lightning-bolt"
3
+ ICON_FREQUENCY = "mdi:cosine-wave"
4
+ ICON_VOLTAGE = "mdi:sine-wave"
@@ -0,0 +1,122 @@
1
+ #pragma once
2
+ #include <cstdint>
3
+
4
+ namespace esphome {
5
+ namespace bl0906 {
6
+
7
+ // Total power conversion
8
+ static const float BL0906_WATT = 16 * 1.097 * 1.097 * (20000 + 20000 + 20000 + 20000 + 20000) /
9
+ (40.41259 * ((5.1 + 5.1) * 1000 / 2000) * 1 * 100 * 1 * 1000);
10
+ // Total Energy conversion
11
+ static const float BL0906_CF = 16 * 4194304 * 0.032768 * 16 /
12
+ (3600000 * 16 *
13
+ (40.4125 * ((5.1 + 5.1) * 1000 / 2000) * 1 * 100 * 1 * 1000 /
14
+ (1.097 * 1.097 * (20000 + 20000 + 20000 + 20000 + 20000))));
15
+ // Frequency conversion
16
+ static const float BL0906_FREF = 10000000;
17
+ // Temperature conversion
18
+ static const float BL0906_TREF = 12.5 / 59 - 40;
19
+ // Current conversion
20
+ static const float BL0906_IREF = 1.097 / (12875 * 1 * (5.1 + 5.1) * 1000 / 2000);
21
+ // Voltage conversion
22
+ static const float BL0906_UREF = 1.097 * (20000 + 20000 + 20000 + 20000 + 20000) / (13162 * 1 * 100 * 1000);
23
+ // Power conversion
24
+ static const float BL0906_PREF = 1.097 * 1.097 * (20000 + 20000 + 20000 + 20000 + 20000) /
25
+ (40.41259 * ((5.1 + 5.1) * 1000 / 2000) * 1 * 100 * 1 * 1000);
26
+ // Energy conversion
27
+ static const float BL0906_EREF = 4194304 * 0.032768 * 16 /
28
+ (3600000 * 16 *
29
+ (40.4125 * ((5.1 + 5.1) * 1000 / 2000) * 1 * 100 * 1 * 1000 /
30
+ (1.097 * 1.097 * (20000 + 20000 + 20000 + 20000 + 20000))));
31
+ // Current coefficient
32
+ static const float BL0906_KI = 12875 * 1 * (5.1 + 5.1) * 1000 / 2000 / 1.097;
33
+ // Power coefficient
34
+ static const float BL0906_KP = 40.4125 * ((5.1 + 5.1) * 1000 / 2000) * 1 * 100 * 1 * 1000 / 1.097 / 1.097 /
35
+ (20000 + 20000 + 20000 + 20000 + 20000);
36
+
37
+ static const uint8_t USR_WRPROT_WITABLE[6] = {0xCA, 0x9E, 0x55, 0x55, 0x00, 0xB7};
38
+ static const uint8_t USR_WRPROT_ONLYREAD[6] = {0xCA, 0x9E, 0x00, 0x00, 0x00, 0x61};
39
+
40
+ static const uint8_t BL0906_READ_COMMAND = 0x35;
41
+ static const uint8_t BL0906_WRITE_COMMAND = 0xCA;
42
+
43
+ // Register address
44
+ // Voltage
45
+ static const uint8_t BL0906_V_RMS = 0x16;
46
+
47
+ // Total power
48
+ static const uint8_t BL0906_WATT_SUM = 0X2C;
49
+
50
+ // Current1~6
51
+ static const uint8_t BL0906_I_1_RMS = 0x0D; // current_1
52
+ static const uint8_t BL0906_I_2_RMS = 0x0E;
53
+ static const uint8_t BL0906_I_3_RMS = 0x0F;
54
+ static const uint8_t BL0906_I_4_RMS = 0x10;
55
+ static const uint8_t BL0906_I_5_RMS = 0x13;
56
+ static const uint8_t BL0906_I_6_RMS = 0x14; // current_6
57
+
58
+ // Power1~6
59
+ static const uint8_t BL0906_WATT_1 = 0X23; // power_1
60
+ static const uint8_t BL0906_WATT_2 = 0X24;
61
+ static const uint8_t BL0906_WATT_3 = 0X25;
62
+ static const uint8_t BL0906_WATT_4 = 0X26;
63
+ static const uint8_t BL0906_WATT_5 = 0X29;
64
+ static const uint8_t BL0906_WATT_6 = 0X2A; // power_6
65
+
66
+ // Active pulse count, unsigned
67
+ static const uint8_t BL0906_CF_1_CNT = 0X30; // Channel_1
68
+ static const uint8_t BL0906_CF_2_CNT = 0X31;
69
+ static const uint8_t BL0906_CF_3_CNT = 0X32;
70
+ static const uint8_t BL0906_CF_4_CNT = 0X33;
71
+ static const uint8_t BL0906_CF_5_CNT = 0X36;
72
+ static const uint8_t BL0906_CF_6_CNT = 0X37; // Channel_6
73
+
74
+ // Total active pulse count, unsigned
75
+ static const uint8_t BL0906_CF_SUM_CNT = 0X39;
76
+
77
+ // Voltage frequency cycle
78
+ static const uint8_t BL0906_FREQUENCY = 0X4E;
79
+
80
+ // Internal temperature
81
+ static const uint8_t BL0906_TEMPERATURE = 0X5E;
82
+
83
+ // Calibration register
84
+ // RMS gain adjustment register
85
+ static const uint8_t BL0906_RMSGN_1 = 0x6D; // Channel_1
86
+ static const uint8_t BL0906_RMSGN_2 = 0x6E;
87
+ static const uint8_t BL0906_RMSGN_3 = 0x6F;
88
+ static const uint8_t BL0906_RMSGN_4 = 0x70;
89
+ static const uint8_t BL0906_RMSGN_5 = 0x73;
90
+ static const uint8_t BL0906_RMSGN_6 = 0x74; // Channel_6
91
+
92
+ // RMS offset correction register
93
+ static const uint8_t BL0906_RMSOS_1 = 0x78; // Channel_1
94
+ static const uint8_t BL0906_RMSOS_2 = 0x79;
95
+ static const uint8_t BL0906_RMSOS_3 = 0x7A;
96
+ static const uint8_t BL0906_RMSOS_4 = 0x7B;
97
+ static const uint8_t BL0906_RMSOS_5 = 0x7E;
98
+ static const uint8_t BL0906_RMSOS_6 = 0x7F; // Channel_6
99
+
100
+ // Active power gain adjustment register
101
+ static const uint8_t BL0906_WATTGN_1 = 0xB7; // Channel_1
102
+ static const uint8_t BL0906_WATTGN_2 = 0xB8;
103
+ static const uint8_t BL0906_WATTGN_3 = 0xB9;
104
+ static const uint8_t BL0906_WATTGN_4 = 0xBA;
105
+ static const uint8_t BL0906_WATTGN_5 = 0xBD;
106
+ static const uint8_t BL0906_WATTGN_6 = 0xBE; // Channel_6
107
+
108
+ // User write protection setting register,
109
+ // You must first write 0x5555 to the write protection setting register before writing to other registers.
110
+ static const uint8_t BL0906_USR_WRPROT = 0x9E;
111
+
112
+ // Reset Register
113
+ static const uint8_t BL0906_SOFT_RESET = 0x9F;
114
+
115
+ const uint8_t BL0906_INIT[2][6] = {
116
+ // Reset to default
117
+ {BL0906_WRITE_COMMAND, BL0906_SOFT_RESET, 0x5A, 0x5A, 0x5A, 0x52},
118
+ // Enable User Operation Write
119
+ {BL0906_WRITE_COMMAND, BL0906_USR_WRPROT, 0x55, 0x55, 0x00, 0xB7}};
120
+
121
+ } // namespace bl0906
122
+ } // namespace esphome