esphome 2025.4.2__py3-none-any.whl → 2025.5.0b3__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 (440) hide show
  1. esphome/__main__.py +16 -14
  2. esphome/components/ac_dimmer/ac_dimmer.cpp +3 -2
  3. esphome/components/adc/__init__.py +51 -34
  4. esphome/components/airthings_wave_base/__init__.py +1 -1
  5. esphome/components/alarm_control_panel/__init__.py +37 -2
  6. esphome/components/am43/cover/__init__.py +4 -5
  7. esphome/components/analog_threshold/analog_threshold_binary_sensor.cpp +6 -4
  8. esphome/components/analog_threshold/analog_threshold_binary_sensor.h +4 -5
  9. esphome/components/analog_threshold/binary_sensor.py +10 -8
  10. esphome/components/anova/climate.py +4 -5
  11. esphome/components/api/__init__.py +25 -8
  12. esphome/components/api/api_connection.cpp +81 -13
  13. esphome/components/api/api_connection.h +13 -1
  14. esphome/components/api/api_frame_helper.cpp +232 -177
  15. esphome/components/api/api_frame_helper.h +61 -8
  16. esphome/components/api/api_noise_context.h +13 -4
  17. esphome/components/api/api_pb2.cpp +1422 -1
  18. esphome/components/api/api_pb2.h +255 -1
  19. esphome/components/api/api_pb2_service.cpp +162 -49
  20. esphome/components/api/api_pb2_service.h +90 -51
  21. esphome/components/api/api_pb2_size.h +361 -0
  22. esphome/components/api/api_server.cpp +110 -34
  23. esphome/components/api/api_server.h +8 -0
  24. esphome/components/api/proto.h +86 -17
  25. esphome/components/as7341/as7341.h +1 -1
  26. esphome/components/atm90e32/__init__.py +1 -0
  27. esphome/components/atm90e32/atm90e32.cpp +576 -199
  28. esphome/components/atm90e32/atm90e32.h +128 -31
  29. esphome/components/atm90e32/atm90e32_reg.h +4 -2
  30. esphome/components/atm90e32/button/__init__.py +62 -10
  31. esphome/components/atm90e32/button/atm90e32_button.cpp +63 -4
  32. esphome/components/atm90e32/button/atm90e32_button.h +36 -4
  33. esphome/components/atm90e32/number/__init__.py +130 -0
  34. esphome/components/atm90e32/number/atm90e32_number.h +16 -0
  35. esphome/components/atm90e32/sensor.py +21 -4
  36. esphome/components/atm90e32/text_sensor/__init__.py +48 -0
  37. esphome/components/audio/__init__.py +96 -49
  38. esphome/components/audio/audio.h +48 -0
  39. esphome/components/audio/audio_decoder.cpp +1 -1
  40. esphome/components/audio/audio_resampler.cpp +2 -0
  41. esphome/components/audio/audio_resampler.h +1 -0
  42. esphome/components/ballu/climate.py +2 -9
  43. esphome/components/bang_bang/climate.py +5 -6
  44. esphome/components/bedjet/bedjet_hub.cpp +1 -0
  45. esphome/components/bedjet/climate/__init__.py +3 -8
  46. esphome/components/bedjet/fan/__init__.py +2 -11
  47. esphome/components/binary/fan/__init__.py +13 -16
  48. esphome/components/binary_sensor/__init__.py +13 -10
  49. esphome/components/bl0906/constants.h +16 -16
  50. esphome/components/ble_client/text_sensor/__init__.py +3 -5
  51. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +4 -6
  52. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +136 -21
  53. esphome/components/bluetooth_proxy/bluetooth_proxy.h +7 -0
  54. esphome/components/button/__init__.py +11 -8
  55. esphome/components/canbus/canbus.cpp +3 -0
  56. esphome/components/canbus/canbus.h +16 -0
  57. esphome/components/ccs811/sensor.py +9 -6
  58. esphome/components/climate/__init__.py +35 -2
  59. esphome/components/climate/climate_mode.h +1 -1
  60. esphome/components/climate/climate_traits.h +63 -57
  61. esphome/components/climate_ir/__init__.py +57 -17
  62. esphome/components/climate_ir_lg/climate.py +2 -5
  63. esphome/components/climate_ir_lg/climate_ir_lg.cpp +7 -7
  64. esphome/components/climate_ir_lg/climate_ir_lg.h +1 -1
  65. esphome/components/color/__init__.py +2 -0
  66. esphome/components/const/__init__.py +5 -0
  67. esphome/components/coolix/climate.py +2 -9
  68. esphome/components/copy/cover/__init__.py +10 -9
  69. esphome/components/copy/fan/__init__.py +11 -9
  70. esphome/components/copy/lock/__init__.py +11 -9
  71. esphome/components/copy/text/__init__.py +9 -6
  72. esphome/components/cover/__init__.py +37 -2
  73. esphome/components/cse7766/cse7766.cpp +2 -1
  74. esphome/components/cst226/binary_sensor/__init__.py +28 -0
  75. esphome/components/cst226/binary_sensor/cs226_button.h +22 -0
  76. esphome/components/cst226/binary_sensor/cstt6_button.cpp +19 -0
  77. esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +27 -5
  78. esphome/components/cst226/touchscreen/cst226_touchscreen.h +10 -10
  79. esphome/components/current_based/cover.py +37 -36
  80. esphome/components/current_based/current_based_cover.cpp +2 -1
  81. esphome/components/daikin/climate.py +2 -9
  82. esphome/components/daikin/daikin.cpp +15 -9
  83. esphome/components/daikin/daikin.h +5 -5
  84. esphome/components/daikin_arc/climate.py +2 -7
  85. esphome/components/daikin_brc/climate.py +3 -5
  86. esphome/components/dallas_temp/dallas_temp.cpp +17 -24
  87. esphome/components/dallas_temp/dallas_temp.h +0 -1
  88. esphome/components/daly_bms/daly_bms.cpp +2 -1
  89. esphome/components/debug/debug_component.cpp +6 -1
  90. esphome/components/debug/debug_component.h +6 -0
  91. esphome/components/debug/debug_esp32.cpp +109 -254
  92. esphome/components/debug/sensor.py +14 -0
  93. esphome/components/deep_sleep/deep_sleep_esp32.cpp +13 -1
  94. esphome/components/delonghi/climate.py +2 -9
  95. esphome/components/demo/__init__.py +18 -20
  96. esphome/components/dfrobot_sen0395/switch/__init__.py +21 -22
  97. esphome/components/dps310/sensor.py +6 -6
  98. esphome/components/ee895/sensor.py +9 -9
  99. esphome/components/emmeti/climate.py +2 -9
  100. esphome/components/endstop/cover.py +17 -16
  101. esphome/components/endstop/endstop_cover.cpp +2 -1
  102. esphome/components/ens160_base/__init__.py +12 -9
  103. esphome/components/esp32/__init__.py +60 -3
  104. esphome/components/esp32/core.cpp +11 -5
  105. esphome/components/esp32/gpio.cpp +86 -24
  106. esphome/components/esp32/gpio.py +15 -16
  107. esphome/components/esp32/gpio_esp32.py +1 -2
  108. esphome/components/esp32/gpio_esp32_c2.py +1 -1
  109. esphome/components/esp32/gpio_esp32_c3.py +1 -1
  110. esphome/components/esp32/gpio_esp32_c6.py +1 -1
  111. esphome/components/esp32/gpio_esp32_h2.py +1 -1
  112. esphome/components/esp32_ble/ble.cpp +1 -0
  113. esphome/components/esp32_ble/ble.h +5 -3
  114. esphome/components/esp32_ble/ble_advertising.cpp +2 -1
  115. esphome/components/esp32_ble/ble_advertising.h +1 -0
  116. esphome/components/esp32_ble_server/__init__.py +3 -0
  117. esphome/components/esp32_ble_tracker/__init__.py +7 -1
  118. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +192 -118
  119. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +29 -3
  120. esphome/components/esp32_camera/esp32_camera.cpp +2 -1
  121. esphome/components/esp32_camera/esp32_camera.h +1 -1
  122. esphome/components/esp32_can/esp32_can.cpp +1 -1
  123. esphome/components/esp32_improv/esp32_improv_component.cpp +1 -1
  124. esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
  125. esphome/components/esp32_rmt_led_strip/led_strip.h +7 -5
  126. esphome/components/esp32_rmt_led_strip/light.py +9 -1
  127. esphome/components/esp32_touch/esp32_touch.cpp +1 -1
  128. esphome/components/esp8266/gpio.cpp +69 -8
  129. esphome/components/ethernet/ethernet_component.cpp +1 -1
  130. esphome/components/event/__init__.py +13 -10
  131. esphome/components/factory_reset/switch/__init__.py +7 -21
  132. esphome/components/fan/__init__.py +52 -5
  133. esphome/components/fastled_base/__init__.py +1 -4
  134. esphome/components/fastled_base/fastled_light.cpp +1 -1
  135. esphome/components/feedback/cover.py +38 -33
  136. esphome/components/feedback/feedback_cover.cpp +2 -1
  137. esphome/components/fujitsu_general/climate.py +2 -9
  138. esphome/components/gcja5/gcja5.cpp +2 -1
  139. esphome/components/gpio/one_wire/gpio_one_wire.cpp +45 -43
  140. esphome/components/gpio/one_wire/gpio_one_wire.h +2 -1
  141. esphome/components/gpio_expander/cached_gpio.h +22 -7
  142. esphome/components/gps/__init__.py +47 -17
  143. esphome/components/gps/gps.cpp +42 -23
  144. esphome/components/gps/gps.h +17 -13
  145. esphome/components/graph/__init__.py +1 -2
  146. esphome/components/gree/climate.py +4 -6
  147. esphome/components/gree/gree.cpp +16 -2
  148. esphome/components/gree/gree.h +2 -2
  149. esphome/components/growatt_solar/growatt_solar.cpp +2 -1
  150. esphome/components/haier/climate.py +37 -34
  151. esphome/components/hbridge/fan/__init__.py +19 -17
  152. esphome/components/he60r/cover.py +4 -5
  153. esphome/components/heatpumpir/climate.py +3 -6
  154. esphome/components/hitachi_ac344/climate.py +2 -9
  155. esphome/components/hitachi_ac424/climate.py +2 -9
  156. esphome/components/hm3301/hm3301.h +1 -1
  157. esphome/components/hte501/sensor.py +6 -6
  158. esphome/components/http_request/__init__.py +39 -6
  159. esphome/components/http_request/http_request.cpp +20 -0
  160. esphome/components/http_request/http_request.h +57 -15
  161. esphome/components/http_request/http_request_arduino.cpp +22 -6
  162. esphome/components/http_request/http_request_arduino.h +4 -3
  163. esphome/components/http_request/http_request_host.cpp +141 -0
  164. esphome/components/http_request/http_request_host.h +37 -0
  165. esphome/components/http_request/http_request_idf.cpp +35 -3
  166. esphome/components/http_request/http_request_idf.h +10 -3
  167. esphome/components/http_request/httplib.h +9691 -0
  168. esphome/components/http_request/update/__init__.py +11 -8
  169. esphome/components/hyt271/sensor.py +6 -6
  170. esphome/components/i2c/i2c.h +4 -0
  171. esphome/components/i2c/i2c_bus_esp_idf.cpp +1 -1
  172. esphome/components/i2s_audio/__init__.py +131 -22
  173. esphome/components/i2s_audio/i2s_audio.h +44 -4
  174. esphome/components/i2s_audio/media_player/__init__.py +19 -9
  175. esphome/components/i2s_audio/microphone/__init__.py +63 -5
  176. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +351 -61
  177. esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +40 -6
  178. esphome/components/i2s_audio/speaker/__init__.py +31 -5
  179. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +155 -19
  180. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +17 -4
  181. esphome/components/ili9xxx/ili9xxx_init.h +1 -1
  182. esphome/components/image/__init__.py +37 -17
  183. esphome/components/image/image.cpp +25 -8
  184. esphome/components/internal_temperature/internal_temperature.cpp +6 -4
  185. esphome/components/key_collector/__init__.py +35 -0
  186. esphome/components/key_collector/key_collector.cpp +8 -0
  187. esphome/components/key_collector/key_collector.h +10 -0
  188. esphome/components/kuntze/kuntze.cpp +2 -1
  189. esphome/components/ld2410/ld2410.h +1 -1
  190. esphome/components/ld2450/ld2450.h +1 -1
  191. esphome/components/light/__init__.py +57 -0
  192. esphome/components/lock/__init__.py +51 -4
  193. esphome/components/lock/automation.h +2 -13
  194. esphome/components/logger/__init__.py +22 -0
  195. esphome/components/logger/logger.cpp +154 -103
  196. esphome/components/logger/logger.h +211 -36
  197. esphome/components/logger/task_log_buffer.cpp +138 -0
  198. esphome/components/logger/task_log_buffer.h +69 -0
  199. esphome/components/lvgl/__init__.py +13 -5
  200. esphome/components/lvgl/automation.py +50 -1
  201. esphome/components/lvgl/defines.py +0 -1
  202. esphome/components/lvgl/lvgl_esphome.cpp +5 -1
  203. esphome/components/lvgl/text/__init__.py +1 -2
  204. esphome/components/mapping/__init__.py +134 -0
  205. esphome/components/matrix_keypad/matrix_keypad.cpp +2 -1
  206. esphome/components/max7219digit/max7219digit.cpp +28 -27
  207. esphome/components/mdns/__init__.py +11 -5
  208. esphome/components/mdns/mdns_component.cpp +11 -5
  209. esphome/components/mdns/mdns_component.h +3 -2
  210. esphome/components/mdns/mdns_esp32.cpp +4 -3
  211. esphome/components/mdns/mdns_esp8266.cpp +4 -2
  212. esphome/components/mdns/mdns_libretiny.cpp +4 -2
  213. esphome/components/mdns/mdns_rp2040.cpp +4 -2
  214. esphome/components/media_player/__init__.py +33 -1
  215. esphome/components/mhz19/sensor.py +11 -7
  216. esphome/components/micro_wake_word/__init__.py +99 -31
  217. esphome/components/micro_wake_word/automation.h +54 -0
  218. esphome/components/micro_wake_word/micro_wake_word.cpp +331 -319
  219. esphome/components/micro_wake_word/micro_wake_word.h +58 -105
  220. esphome/components/micro_wake_word/preprocessor_settings.h +19 -2
  221. esphome/components/micro_wake_word/streaming_model.cpp +158 -41
  222. esphome/components/micro_wake_word/streaming_model.h +85 -13
  223. esphome/components/microphone/__init__.py +139 -9
  224. esphome/components/microphone/automation.h +14 -2
  225. esphome/components/microphone/microphone.cpp +21 -0
  226. esphome/components/microphone/microphone.h +14 -5
  227. esphome/components/microphone/microphone_source.cpp +95 -0
  228. esphome/components/microphone/microphone_source.h +80 -0
  229. esphome/components/mics_4514/sensor.py +25 -14
  230. esphome/components/midea/climate.py +3 -4
  231. esphome/components/midea_ir/climate.py +3 -5
  232. esphome/components/mipi_spi/__init__.py +15 -0
  233. esphome/components/mipi_spi/display.py +474 -0
  234. esphome/components/mipi_spi/mipi_spi.cpp +481 -0
  235. esphome/components/mipi_spi/mipi_spi.h +171 -0
  236. esphome/components/mipi_spi/models/__init__.py +65 -0
  237. esphome/components/mipi_spi/models/amoled.py +72 -0
  238. esphome/components/mipi_spi/models/commands.py +82 -0
  239. esphome/components/mipi_spi/models/cyd.py +10 -0
  240. esphome/components/mipi_spi/models/ili.py +749 -0
  241. esphome/components/mipi_spi/models/jc.py +260 -0
  242. esphome/components/mipi_spi/models/lanbon.py +15 -0
  243. esphome/components/mipi_spi/models/lilygo.py +60 -0
  244. esphome/components/mipi_spi/models/waveshare.py +139 -0
  245. esphome/components/mitsubishi/climate.py +2 -5
  246. esphome/components/mitsubishi/mitsubishi.cpp +9 -9
  247. esphome/components/mixer/speaker/mixer_speaker.cpp +12 -22
  248. esphome/components/mixer/speaker/mixer_speaker.h +1 -3
  249. esphome/components/mlx90393/sensor.py +5 -0
  250. esphome/components/mlx90393/sensor_mlx90393.cpp +195 -13
  251. esphome/components/mlx90393/sensor_mlx90393.h +21 -4
  252. esphome/components/modbus/modbus.cpp +2 -1
  253. esphome/components/mqtt/__init__.py +1 -1
  254. esphome/components/mqtt/mqtt_client.cpp +6 -2
  255. esphome/components/mqtt/mqtt_const.h +4 -0
  256. esphome/components/mqtt/mqtt_fan.cpp +39 -0
  257. esphome/components/mqtt/mqtt_fan.h +2 -0
  258. esphome/components/ms5611/sensor.py +6 -6
  259. esphome/components/ms8607/sensor.py +3 -3
  260. esphome/components/network/__init__.py +1 -1
  261. esphome/components/nextion/base_component.py +17 -16
  262. esphome/components/nextion/display.py +11 -2
  263. esphome/components/nextion/nextion.cpp +39 -1
  264. esphome/components/nextion/nextion.h +50 -0
  265. esphome/components/noblex/climate.py +2 -9
  266. esphome/components/number/__init__.py +12 -9
  267. esphome/components/one_wire/one_wire_bus.cpp +14 -10
  268. esphome/components/one_wire/one_wire_bus.h +14 -8
  269. esphome/components/online_image/bmp_image.cpp +48 -11
  270. esphome/components/online_image/bmp_image.h +2 -0
  271. esphome/components/opentherm/binary_sensor/__init__.py +2 -4
  272. esphome/components/opentherm/number/__init__.py +11 -20
  273. esphome/components/opentherm/sensor/__init__.py +3 -3
  274. esphome/components/opentherm/switch/__init__.py +3 -5
  275. esphome/components/output/lock/__init__.py +11 -9
  276. esphome/components/packages/__init__.py +33 -31
  277. esphome/components/packet_transport/__init__.py +201 -0
  278. esphome/components/packet_transport/binary_sensor.py +19 -0
  279. esphome/components/packet_transport/packet_transport.cpp +534 -0
  280. esphome/components/packet_transport/packet_transport.h +154 -0
  281. esphome/components/packet_transport/sensor.py +19 -0
  282. esphome/components/pca9685/pca9685_output.cpp +2 -1
  283. esphome/components/pid/climate.py +2 -4
  284. esphome/components/pm2005/__init__.py +1 -0
  285. esphome/components/pm2005/pm2005.cpp +123 -0
  286. esphome/components/pm2005/pm2005.h +46 -0
  287. esphome/components/pm2005/sensor.py +86 -0
  288. esphome/components/pmsa003i/pmsa003i.cpp +43 -16
  289. esphome/components/pmsa003i/pmsa003i.h +25 -25
  290. esphome/components/pmsx003/pmsx003.cpp +195 -230
  291. esphome/components/pmsx003/pmsx003.h +51 -33
  292. esphome/components/pmsx003/sensor.py +21 -11
  293. esphome/components/pn7150/pn7150.h +2 -2
  294. esphome/components/pn7160/pn7160.h +2 -2
  295. esphome/components/prometheus/prometheus_handler.cpp +174 -0
  296. esphome/components/prometheus/prometheus_handler.h +17 -0
  297. esphome/components/psram/__init__.py +7 -5
  298. esphome/components/pulse_meter/pulse_meter_sensor.cpp +32 -12
  299. esphome/components/pulse_meter/pulse_meter_sensor.h +5 -5
  300. esphome/components/pzem004t/pzem004t.cpp +2 -1
  301. esphome/components/qspi_dbi/__init__.py +0 -1
  302. esphome/components/qspi_dbi/display.py +2 -1
  303. esphome/components/qspi_dbi/models.py +1 -2
  304. esphome/components/remote_base/__init__.py +91 -0
  305. esphome/components/remote_base/beo4_protocol.cpp +153 -0
  306. esphome/components/remote_base/beo4_protocol.h +43 -0
  307. esphome/components/remote_base/gobox_protocol.cpp +131 -0
  308. esphome/components/remote_base/gobox_protocol.h +54 -0
  309. esphome/components/remote_receiver/remote_receiver_esp32.cpp +16 -9
  310. esphome/components/resampler/speaker/resampler_speaker.cpp +12 -10
  311. esphome/components/resampler/speaker/resampler_speaker.h +1 -1
  312. esphome/components/rf_bridge/rf_bridge.cpp +2 -1
  313. esphome/components/scd30/sensor.py +2 -3
  314. esphome/components/scd4x/sensor.py +4 -5
  315. esphome/components/sdp3x/sensor.py +2 -1
  316. esphome/components/sds011/sds011.cpp +2 -1
  317. esphome/components/select/__init__.py +19 -20
  318. esphome/components/sen5x/sen5x.cpp +55 -36
  319. esphome/components/sen5x/sensor.py +1 -1
  320. esphome/components/senseair/sensor.py +3 -3
  321. esphome/components/sensor/__init__.py +158 -14
  322. esphome/components/sensor/filter.cpp +23 -0
  323. esphome/components/sensor/filter.h +22 -0
  324. esphome/components/sgp30/sensor.py +14 -16
  325. esphome/components/sgp4x/sensor.py +1 -1
  326. esphome/components/sht4x/sht4x.cpp +43 -22
  327. esphome/components/sht4x/sht4x.h +1 -1
  328. esphome/components/shtcx/sensor.py +6 -6
  329. esphome/components/slow_pwm/slow_pwm_output.cpp +2 -1
  330. esphome/components/sml/text_sensor/__init__.py +4 -6
  331. esphome/components/sound_level/__init__.py +0 -0
  332. esphome/components/sound_level/sensor.py +97 -0
  333. esphome/components/sound_level/sound_level.cpp +194 -0
  334. esphome/components/sound_level/sound_level.h +73 -0
  335. esphome/components/speaker/media_player/__init__.py +4 -8
  336. esphome/components/speaker/media_player/speaker_media_player.cpp +0 -18
  337. esphome/components/speaker/media_player/speaker_media_player.h +0 -11
  338. esphome/components/speaker/speaker.h +4 -7
  339. esphome/components/speed/fan/__init__.py +17 -16
  340. esphome/components/spi/spi.h +11 -1
  341. esphome/components/sprinkler/__init__.py +18 -19
  342. esphome/components/sprinkler/sprinkler.cpp +6 -5
  343. esphome/components/switch/__init__.py +32 -42
  344. esphome/components/syslog/__init__.py +41 -0
  345. esphome/components/syslog/esphome_syslog.cpp +49 -0
  346. esphome/components/syslog/esphome_syslog.h +27 -0
  347. esphome/components/t6615/sensor.py +3 -3
  348. esphome/components/t6615/t6615.cpp +2 -1
  349. esphome/components/tca9555/tca9555.cpp +11 -6
  350. esphome/components/tcl112/climate.py +2 -9
  351. esphome/components/template/alarm_control_panel/__init__.py +7 -6
  352. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +21 -17
  353. esphome/components/template/alarm_control_panel/template_alarm_control_panel.h +2 -1
  354. esphome/components/template/cover/__init__.py +27 -21
  355. esphome/components/template/fan/__init__.py +14 -12
  356. esphome/components/template/lock/__init__.py +20 -25
  357. esphome/components/template/lock/automation.h +18 -0
  358. esphome/components/template/text/__init__.py +4 -3
  359. esphome/components/template/valve/__init__.py +32 -21
  360. esphome/components/template/valve/automation.h +24 -0
  361. esphome/components/text/__init__.py +32 -1
  362. esphome/components/text_sensor/__init__.py +24 -29
  363. esphome/components/thermostat/climate.py +5 -5
  364. esphome/components/time_based/cover.py +17 -16
  365. esphome/components/time_based/time_based_cover.cpp +2 -1
  366. esphome/components/tm1638/switch/__init__.py +10 -7
  367. esphome/components/tormatic/cover.py +4 -5
  368. esphome/components/toshiba/climate.py +3 -5
  369. esphome/components/touchscreen/touchscreen.cpp +3 -1
  370. esphome/components/tuya/climate/__init__.py +5 -6
  371. esphome/components/tuya/cover/__init__.py +6 -11
  372. esphome/components/tuya/select/__init__.py +15 -5
  373. esphome/components/tuya/select/tuya_select.cpp +6 -1
  374. esphome/components/tuya/select/tuya_select.h +5 -1
  375. esphome/components/uart/packet_transport/__init__.py +20 -0
  376. esphome/components/uart/packet_transport/uart_transport.cpp +88 -0
  377. esphome/components/uart/packet_transport/uart_transport.h +41 -0
  378. esphome/components/uart/switch/uart_switch.cpp +2 -1
  379. esphome/components/udp/__init__.py +126 -128
  380. esphome/components/udp/automation.h +40 -0
  381. esphome/components/udp/binary_sensor.py +3 -25
  382. esphome/components/udp/packet_transport/__init__.py +29 -0
  383. esphome/components/udp/packet_transport/udp_transport.cpp +36 -0
  384. esphome/components/udp/packet_transport/udp_transport.h +28 -0
  385. esphome/components/udp/sensor.py +3 -25
  386. esphome/components/udp/udp_component.cpp +26 -470
  387. esphome/components/udp/udp_component.h +21 -128
  388. esphome/components/update/__init__.py +31 -1
  389. esphome/components/uponor_smatrix/climate/__init__.py +4 -9
  390. esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +2 -1
  391. esphome/components/uponor_smatrix/uponor_smatrix.cpp +2 -1
  392. esphome/components/uptime/text_sensor/__init__.py +47 -7
  393. esphome/components/uptime/text_sensor/uptime_text_sensor.cpp +12 -7
  394. esphome/components/uptime/text_sensor/uptime_text_sensor.h +19 -0
  395. esphome/components/valve/__init__.py +34 -3
  396. esphome/components/valve/automation.h +1 -19
  397. esphome/components/vl53l0x/sensor.py +11 -0
  398. esphome/components/vl53l0x/vl53l0x_sensor.cpp +5 -1
  399. esphome/components/vl53l0x/vl53l0x_sensor.h +2 -1
  400. esphome/components/voice_assistant/__init__.py +36 -10
  401. esphome/components/voice_assistant/voice_assistant.cpp +170 -144
  402. esphome/components/voice_assistant/voice_assistant.h +26 -25
  403. esphome/components/waveshare_epaper/display.py +6 -0
  404. esphome/components/waveshare_epaper/waveshare_epaper.cpp +439 -37
  405. esphome/components/waveshare_epaper/waveshare_epaper.h +60 -11
  406. esphome/components/whirlpool/climate.py +3 -5
  407. esphome/components/whynter/climate.py +3 -5
  408. esphome/components/xpt2046/touchscreen/xpt2046.cpp +1 -1
  409. esphome/components/yashima/climate.py +6 -6
  410. esphome/components/zhlt01/climate.py +2 -7
  411. esphome/config.py +13 -13
  412. esphome/config_validation.py +38 -58
  413. esphome/const.py +15 -1
  414. esphome/core/__init__.py +2 -0
  415. esphome/core/application.cpp +23 -10
  416. esphome/core/application.h +9 -1
  417. esphome/core/automation.h +4 -3
  418. esphome/core/component.cpp +28 -7
  419. esphome/core/component.h +10 -1
  420. esphome/core/defines.h +23 -17
  421. esphome/core/macros.h +4 -0
  422. esphome/core/scheduler.cpp +7 -1
  423. esphome/cpp_generator.py +6 -2
  424. esphome/dashboard/web_server.py +3 -3
  425. esphome/helpers.py +39 -0
  426. esphome/loader.py +4 -0
  427. esphome/log.py +15 -19
  428. esphome/mqtt.py +23 -10
  429. esphome/platformio_api.py +1 -1
  430. esphome/schema_extractors.py +0 -1
  431. esphome/voluptuous_schema.py +3 -1
  432. esphome/vscode.py +15 -0
  433. esphome/wizard.py +47 -37
  434. esphome/zeroconf.py +7 -3
  435. {esphome-2025.4.2.dist-info → esphome-2025.5.0b3.dist-info}/METADATA +10 -11
  436. {esphome-2025.4.2.dist-info → esphome-2025.5.0b3.dist-info}/RECORD +440 -380
  437. {esphome-2025.4.2.dist-info → esphome-2025.5.0b3.dist-info}/WHEEL +1 -1
  438. {esphome-2025.4.2.dist-info → esphome-2025.5.0b3.dist-info}/entry_points.txt +0 -0
  439. {esphome-2025.4.2.dist-info → esphome-2025.5.0b3.dist-info}/licenses/LICENSE +0 -0
  440. {esphome-2025.4.2.dist-info → esphome-2025.5.0b3.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,6 @@
1
1
  #pragma once
2
2
 
3
+ #include <unordered_map>
3
4
  #include "atm90e32_reg.h"
4
5
  #include "esphome/components/sensor/sensor.h"
5
6
  #include "esphome/components/spi/spi.h"
@@ -18,6 +19,26 @@ class ATM90E32Component : public PollingComponent,
18
19
  static const uint8_t PHASEA = 0;
19
20
  static const uint8_t PHASEB = 1;
20
21
  static const uint8_t PHASEC = 2;
22
+ const char *phase_labels[3] = {"A", "B", "C"};
23
+ // these registers are not sucessive, so we can't just do 'base + phase'
24
+ const uint16_t voltage_gain_registers[3] = {ATM90E32_REGISTER_UGAINA, ATM90E32_REGISTER_UGAINB,
25
+ ATM90E32_REGISTER_UGAINC};
26
+ const uint16_t current_gain_registers[3] = {ATM90E32_REGISTER_IGAINA, ATM90E32_REGISTER_IGAINB,
27
+ ATM90E32_REGISTER_IGAINC};
28
+ const uint16_t voltage_offset_registers[3] = {ATM90E32_REGISTER_UOFFSETA, ATM90E32_REGISTER_UOFFSETB,
29
+ ATM90E32_REGISTER_UOFFSETC};
30
+ const uint16_t current_offset_registers[3] = {ATM90E32_REGISTER_IOFFSETA, ATM90E32_REGISTER_IOFFSETB,
31
+ ATM90E32_REGISTER_IOFFSETC};
32
+ const uint16_t power_offset_registers[3] = {ATM90E32_REGISTER_POFFSETA, ATM90E32_REGISTER_POFFSETB,
33
+ ATM90E32_REGISTER_POFFSETC};
34
+ const uint16_t reactive_power_offset_registers[3] = {ATM90E32_REGISTER_QOFFSETA, ATM90E32_REGISTER_QOFFSETB,
35
+ ATM90E32_REGISTER_QOFFSETC};
36
+ const uint16_t over_voltage_flags[3] = {ATM90E32_STATUS_S0_OVPHASEAST, ATM90E32_STATUS_S0_OVPHASEBST,
37
+ ATM90E32_STATUS_S0_OVPHASECST};
38
+ const uint16_t voltage_sag_flags[3] = {ATM90E32_STATUS_S1_SAGPHASEAST, ATM90E32_STATUS_S1_SAGPHASEBST,
39
+ ATM90E32_STATUS_S1_SAGPHASECST};
40
+ const uint16_t phase_loss_flags[3] = {ATM90E32_STATUS_S1_PHASELOSSAST, ATM90E32_STATUS_S1_PHASELOSSBST,
41
+ ATM90E32_STATUS_S1_PHASELOSSCST};
21
42
  void loop() override;
22
43
  void setup() override;
23
44
  void dump_config() override;
@@ -42,6 +63,14 @@ class ATM90E32Component : public PollingComponent,
42
63
  void set_peak_current_sensor(int phase, sensor::Sensor *obj) { this->phase_[phase].peak_current_sensor_ = obj; }
43
64
  void set_volt_gain(int phase, uint16_t gain) { this->phase_[phase].voltage_gain_ = gain; }
44
65
  void set_ct_gain(int phase, uint16_t gain) { this->phase_[phase].ct_gain_ = gain; }
66
+ void set_voltage_offset(uint8_t phase, int16_t offset) { this->offset_phase_[phase].voltage_offset_ = offset; }
67
+ void set_current_offset(uint8_t phase, int16_t offset) { this->offset_phase_[phase].current_offset_ = offset; }
68
+ void set_active_power_offset(uint8_t phase, int16_t offset) {
69
+ this->power_offset_phase_[phase].active_power_offset = offset;
70
+ }
71
+ void set_reactive_power_offset(uint8_t phase, int16_t offset) {
72
+ this->power_offset_phase_[phase].reactive_power_offset = offset;
73
+ }
45
74
  void set_freq_sensor(sensor::Sensor *freq_sensor) { freq_sensor_ = freq_sensor; }
46
75
  void set_peak_current_signed(bool flag) { peak_current_signed_ = flag; }
47
76
  void set_chip_temperature_sensor(sensor::Sensor *chip_temperature_sensor) {
@@ -51,53 +80,104 @@ class ATM90E32Component : public PollingComponent,
51
80
  void set_current_phases(int phases) { current_phases_ = phases; }
52
81
  void set_pga_gain(uint16_t gain) { pga_gain_ = gain; }
53
82
  void run_offset_calibrations();
83
+ void run_power_offset_calibrations();
54
84
  void clear_offset_calibrations();
85
+ void clear_power_offset_calibrations();
86
+ void clear_gain_calibrations();
55
87
  void set_enable_offset_calibration(bool flag) { enable_offset_calibration_ = flag; }
56
- uint16_t calibrate_voltage_offset_phase(uint8_t /*phase*/);
57
- uint16_t calibrate_current_offset_phase(uint8_t /*phase*/);
88
+ void set_enable_gain_calibration(bool flag) { enable_gain_calibration_ = flag; }
89
+ int16_t calibrate_offset(uint8_t phase, bool voltage);
90
+ int16_t calibrate_power_offset(uint8_t phase, bool reactive);
91
+ void run_gain_calibrations();
92
+ #ifdef USE_NUMBER
93
+ void set_reference_voltage(uint8_t phase, number::Number *ref_voltage) { ref_voltages_[phase] = ref_voltage; }
94
+ void set_reference_current(uint8_t phase, number::Number *ref_current) { ref_currents_[phase] = ref_current; }
95
+ #endif
96
+ float get_reference_voltage(uint8_t phase) {
97
+ #ifdef USE_NUMBER
98
+ return (phase >= 0 && phase < 3 && ref_voltages_[phase]) ? ref_voltages_[phase]->state : 120.0; // Default voltage
99
+ #else
100
+ return 120.0; // Default voltage
101
+ #endif
102
+ }
103
+ float get_reference_current(uint8_t phase) {
104
+ #ifdef USE_NUMBER
105
+ return (phase >= 0 && phase < 3 && ref_currents_[phase]) ? ref_currents_[phase]->state : 5.0f; // Default current
106
+ #else
107
+ return 5.0f; // Default current
108
+ #endif
109
+ }
110
+ bool using_saved_calibrations_ = false; // Track if stored calibrations are being used
111
+ #ifdef USE_TEXT_SENSOR
112
+ void check_phase_status();
113
+ void check_freq_status();
114
+ void check_over_current();
115
+ void set_phase_status_text_sensor(uint8_t phase, text_sensor::TextSensor *sensor) {
116
+ this->phase_status_text_sensor_[phase] = sensor;
117
+ }
118
+ void set_freq_status_text_sensor(text_sensor::TextSensor *sensor) { this->freq_status_text_sensor_ = sensor; }
119
+ #endif
120
+ uint16_t calculate_voltage_threshold(int line_freq, uint16_t ugain, float multiplier);
58
121
  int32_t last_periodic_millis = millis();
59
122
 
60
123
  protected:
124
+ #ifdef USE_NUMBER
125
+ number::Number *ref_voltages_[3]{nullptr, nullptr, nullptr};
126
+ number::Number *ref_currents_[3]{nullptr, nullptr, nullptr};
127
+ #endif
61
128
  uint16_t read16_(uint16_t a_register);
62
129
  int read32_(uint16_t addr_h, uint16_t addr_l);
63
130
  void write16_(uint16_t a_register, uint16_t val);
64
- float get_local_phase_voltage_(uint8_t /*phase*/);
65
- float get_local_phase_current_(uint8_t /*phase*/);
66
- float get_local_phase_active_power_(uint8_t /*phase*/);
67
- float get_local_phase_reactive_power_(uint8_t /*phase*/);
68
- float get_local_phase_power_factor_(uint8_t /*phase*/);
69
- float get_local_phase_forward_active_energy_(uint8_t /*phase*/);
70
- float get_local_phase_reverse_active_energy_(uint8_t /*phase*/);
71
- float get_local_phase_angle_(uint8_t /*phase*/);
72
- float get_local_phase_harmonic_active_power_(uint8_t /*phase*/);
73
- float get_local_phase_peak_current_(uint8_t /*phase*/);
74
- float get_phase_voltage_(uint8_t /*phase*/);
75
- float get_phase_voltage_avg_(uint8_t /*phase*/);
76
- float get_phase_current_(uint8_t /*phase*/);
77
- float get_phase_current_avg_(uint8_t /*phase*/);
78
- float get_phase_active_power_(uint8_t /*phase*/);
79
- float get_phase_reactive_power_(uint8_t /*phase*/);
80
- float get_phase_power_factor_(uint8_t /*phase*/);
81
- float get_phase_forward_active_energy_(uint8_t /*phase*/);
82
- float get_phase_reverse_active_energy_(uint8_t /*phase*/);
83
- float get_phase_angle_(uint8_t /*phase*/);
84
- float get_phase_harmonic_active_power_(uint8_t /*phase*/);
85
- float get_phase_peak_current_(uint8_t /*phase*/);
131
+ float get_local_phase_voltage_(uint8_t phase);
132
+ float get_local_phase_current_(uint8_t phase);
133
+ float get_local_phase_active_power_(uint8_t phase);
134
+ float get_local_phase_reactive_power_(uint8_t phase);
135
+ float get_local_phase_apparent_power_(uint8_t phase);
136
+ float get_local_phase_power_factor_(uint8_t phase);
137
+ float get_local_phase_forward_active_energy_(uint8_t phase);
138
+ float get_local_phase_reverse_active_energy_(uint8_t phase);
139
+ float get_local_phase_angle_(uint8_t phase);
140
+ float get_local_phase_harmonic_active_power_(uint8_t phase);
141
+ float get_local_phase_peak_current_(uint8_t phase);
142
+ float get_phase_voltage_(uint8_t phase);
143
+ float get_phase_voltage_avg_(uint8_t phase);
144
+ float get_phase_current_(uint8_t phase);
145
+ float get_phase_current_avg_(uint8_t phase);
146
+ float get_phase_active_power_(uint8_t phase);
147
+ float get_phase_reactive_power_(uint8_t phase);
148
+ float get_phase_apparent_power_(uint8_t phase);
149
+ float get_phase_power_factor_(uint8_t phase);
150
+ float get_phase_forward_active_energy_(uint8_t phase);
151
+ float get_phase_reverse_active_energy_(uint8_t phase);
152
+ float get_phase_angle_(uint8_t phase);
153
+ float get_phase_harmonic_active_power_(uint8_t phase);
154
+ float get_phase_peak_current_(uint8_t phase);
86
155
  float get_frequency_();
87
156
  float get_chip_temperature_();
88
157
  bool get_publish_interval_flag_() { return publish_interval_flag_; };
89
158
  void set_publish_interval_flag_(bool flag) { publish_interval_flag_ = flag; };
90
- void restore_calibrations_();
159
+ void restore_offset_calibrations_();
160
+ void restore_power_offset_calibrations_();
161
+ void restore_gain_calibrations_();
162
+ void save_gain_calibration_to_memory_();
163
+ void write_offsets_to_registers_(uint8_t phase, int16_t voltage_offset, int16_t current_offset);
164
+ void write_power_offsets_to_registers_(uint8_t phase, int16_t p_offset, int16_t q_offset);
165
+ void write_gains_to_registers_();
166
+ bool verify_gain_writes_();
167
+ bool validate_spi_read_(uint16_t expected, const char *context = nullptr);
91
168
 
92
169
  struct ATM90E32Phase {
93
170
  uint16_t voltage_gain_{0};
94
171
  uint16_t ct_gain_{0};
95
- uint16_t voltage_offset_{0};
96
- uint16_t current_offset_{0};
172
+ int16_t voltage_offset_{0};
173
+ int16_t current_offset_{0};
174
+ int16_t active_power_offset_{0};
175
+ int16_t reactive_power_offset_{0};
97
176
  float voltage_{0};
98
177
  float current_{0};
99
178
  float active_power_{0};
100
179
  float reactive_power_{0};
180
+ float apparent_power_{0};
101
181
  float power_factor_{0};
102
182
  float forward_active_energy_{0};
103
183
  float reverse_active_energy_{0};
@@ -119,14 +199,30 @@ class ATM90E32Component : public PollingComponent,
119
199
  uint32_t cumulative_reverse_active_energy_{0};
120
200
  } phase_[3];
121
201
 
122
- struct Calibration {
123
- uint16_t voltage_offset_{0};
124
- uint16_t current_offset_{0};
202
+ struct OffsetCalibration {
203
+ int16_t voltage_offset_{0};
204
+ int16_t current_offset_{0};
125
205
  } offset_phase_[3];
126
206
 
127
- ESPPreferenceObject pref_;
207
+ struct PowerOffsetCalibration {
208
+ int16_t active_power_offset{0};
209
+ int16_t reactive_power_offset{0};
210
+ } power_offset_phase_[3];
211
+
212
+ struct GainCalibration {
213
+ uint16_t voltage_gain{1};
214
+ uint16_t current_gain{1};
215
+ } gain_phase_[3];
216
+
217
+ ESPPreferenceObject offset_pref_;
218
+ ESPPreferenceObject power_offset_pref_;
219
+ ESPPreferenceObject gain_calibration_pref_;
128
220
 
129
221
  sensor::Sensor *freq_sensor_{nullptr};
222
+ #ifdef USE_TEXT_SENSOR
223
+ text_sensor::TextSensor *phase_status_text_sensor_[3]{nullptr};
224
+ text_sensor::TextSensor *freq_status_text_sensor_{nullptr};
225
+ #endif
130
226
  sensor::Sensor *chip_temperature_sensor_{nullptr};
131
227
  uint16_t pga_gain_{0x15};
132
228
  int line_freq_{60};
@@ -134,6 +230,7 @@ class ATM90E32Component : public PollingComponent,
134
230
  bool publish_interval_flag_{false};
135
231
  bool peak_current_signed_{false};
136
232
  bool enable_offset_calibration_{false};
233
+ bool enable_gain_calibration_{false};
137
234
  };
138
235
 
139
236
  } // namespace atm90e32
@@ -176,16 +176,17 @@ static const uint16_t ATM90E32_REGISTER_ANENERGYCH = 0xAF; // C Reverse Harm. E
176
176
 
177
177
  /* POWER & P.F. REGISTERS */
178
178
  static const uint16_t ATM90E32_REGISTER_PMEANT = 0xB0; // Total Mean Power (P)
179
- static const uint16_t ATM90E32_REGISTER_PMEAN = 0xB1; // Mean Power Reg Base (P)
179
+ static const uint16_t ATM90E32_REGISTER_PMEAN = 0xB1; // Active Power Reg Base (P)
180
180
  static const uint16_t ATM90E32_REGISTER_PMEANA = 0xB1; // A Mean Power (P)
181
181
  static const uint16_t ATM90E32_REGISTER_PMEANB = 0xB2; // B Mean Power (P)
182
182
  static const uint16_t ATM90E32_REGISTER_PMEANC = 0xB3; // C Mean Power (P)
183
183
  static const uint16_t ATM90E32_REGISTER_QMEANT = 0xB4; // Total Mean Power (Q)
184
- static const uint16_t ATM90E32_REGISTER_QMEAN = 0xB5; // Mean Power Reg Base (Q)
184
+ static const uint16_t ATM90E32_REGISTER_QMEAN = 0xB5; // Reactive Power Reg Base (Q)
185
185
  static const uint16_t ATM90E32_REGISTER_QMEANA = 0xB5; // A Mean Power (Q)
186
186
  static const uint16_t ATM90E32_REGISTER_QMEANB = 0xB6; // B Mean Power (Q)
187
187
  static const uint16_t ATM90E32_REGISTER_QMEANC = 0xB7; // C Mean Power (Q)
188
188
  static const uint16_t ATM90E32_REGISTER_SMEANT = 0xB8; // Total Mean Power (S)
189
+ static const uint16_t ATM90E32_REGISTER_SMEAN = 0xB9; // Apparent Mean Power Base (S)
189
190
  static const uint16_t ATM90E32_REGISTER_SMEANA = 0xB9; // A Mean Power (S)
190
191
  static const uint16_t ATM90E32_REGISTER_SMEANB = 0xBA; // B Mean Power (S)
191
192
  static const uint16_t ATM90E32_REGISTER_SMEANC = 0xBB; // C Mean Power (S)
@@ -206,6 +207,7 @@ static const uint16_t ATM90E32_REGISTER_QMEANALSB = 0xC5; // Lower Word (A Rea
206
207
  static const uint16_t ATM90E32_REGISTER_QMEANBLSB = 0xC6; // Lower Word (B React. Power)
207
208
  static const uint16_t ATM90E32_REGISTER_QMEANCLSB = 0xC7; // Lower Word (C React. Power)
208
209
  static const uint16_t ATM90E32_REGISTER_SAMEANTLSB = 0xC8; // Lower Word (Tot. App. Power)
210
+ static const uint16_t ATM90E32_REGISTER_SMEANLSB = 0xC9; // Lower Word Reg Base (Apparent Power)
209
211
  static const uint16_t ATM90E32_REGISTER_SMEANALSB = 0xC9; // Lower Word (A App. Power)
210
212
  static const uint16_t ATM90E32_REGISTER_SMEANBLSB = 0xCA; // Lower Word (B App. Power)
211
213
  static const uint16_t ATM90E32_REGISTER_SMEANCLSB = 0xCB; // Lower Word (C App. Power)
@@ -1,43 +1,95 @@
1
1
  import esphome.codegen as cg
2
2
  from esphome.components import button
3
3
  import esphome.config_validation as cv
4
- from esphome.const import CONF_ID, ENTITY_CATEGORY_CONFIG, ICON_CHIP, ICON_SCALE
4
+ from esphome.const import CONF_ID, ENTITY_CATEGORY_CONFIG, ICON_SCALE
5
5
 
6
6
  from .. import atm90e32_ns
7
7
  from ..sensor import ATM90E32Component
8
8
 
9
+ CONF_RUN_GAIN_CALIBRATION = "run_gain_calibration"
10
+ CONF_CLEAR_GAIN_CALIBRATION = "clear_gain_calibration"
9
11
  CONF_RUN_OFFSET_CALIBRATION = "run_offset_calibration"
10
12
  CONF_CLEAR_OFFSET_CALIBRATION = "clear_offset_calibration"
13
+ CONF_RUN_POWER_OFFSET_CALIBRATION = "run_power_offset_calibration"
14
+ CONF_CLEAR_POWER_OFFSET_CALIBRATION = "clear_power_offset_calibration"
11
15
 
12
- ATM90E32CalibrationButton = atm90e32_ns.class_(
13
- "ATM90E32CalibrationButton",
14
- button.Button,
16
+ ATM90E32GainCalibrationButton = atm90e32_ns.class_(
17
+ "ATM90E32GainCalibrationButton", button.Button
15
18
  )
16
- ATM90E32ClearCalibrationButton = atm90e32_ns.class_(
17
- "ATM90E32ClearCalibrationButton",
18
- button.Button,
19
+ ATM90E32ClearGainCalibrationButton = atm90e32_ns.class_(
20
+ "ATM90E32ClearGainCalibrationButton", button.Button
21
+ )
22
+ ATM90E32OffsetCalibrationButton = atm90e32_ns.class_(
23
+ "ATM90E32OffsetCalibrationButton", button.Button
24
+ )
25
+ ATM90E32ClearOffsetCalibrationButton = atm90e32_ns.class_(
26
+ "ATM90E32ClearOffsetCalibrationButton", button.Button
27
+ )
28
+ ATM90E32PowerOffsetCalibrationButton = atm90e32_ns.class_(
29
+ "ATM90E32PowerOffsetCalibrationButton", button.Button
30
+ )
31
+ ATM90E32ClearPowerOffsetCalibrationButton = atm90e32_ns.class_(
32
+ "ATM90E32ClearPowerOffsetCalibrationButton", button.Button
19
33
  )
20
34
 
21
35
  CONFIG_SCHEMA = {
22
36
  cv.GenerateID(CONF_ID): cv.use_id(ATM90E32Component),
37
+ cv.Optional(CONF_RUN_GAIN_CALIBRATION): button.button_schema(
38
+ ATM90E32GainCalibrationButton,
39
+ entity_category=ENTITY_CATEGORY_CONFIG,
40
+ icon="mdi:scale-balance",
41
+ ),
42
+ cv.Optional(CONF_CLEAR_GAIN_CALIBRATION): button.button_schema(
43
+ ATM90E32ClearGainCalibrationButton,
44
+ entity_category=ENTITY_CATEGORY_CONFIG,
45
+ icon="mdi:delete",
46
+ ),
23
47
  cv.Optional(CONF_RUN_OFFSET_CALIBRATION): button.button_schema(
24
- ATM90E32CalibrationButton,
48
+ ATM90E32OffsetCalibrationButton,
25
49
  entity_category=ENTITY_CATEGORY_CONFIG,
26
50
  icon=ICON_SCALE,
27
51
  ),
28
52
  cv.Optional(CONF_CLEAR_OFFSET_CALIBRATION): button.button_schema(
29
- ATM90E32ClearCalibrationButton,
53
+ ATM90E32ClearOffsetCalibrationButton,
54
+ entity_category=ENTITY_CATEGORY_CONFIG,
55
+ icon="mdi:delete",
56
+ ),
57
+ cv.Optional(CONF_RUN_POWER_OFFSET_CALIBRATION): button.button_schema(
58
+ ATM90E32PowerOffsetCalibrationButton,
30
59
  entity_category=ENTITY_CATEGORY_CONFIG,
31
- icon=ICON_CHIP,
60
+ icon=ICON_SCALE,
61
+ ),
62
+ cv.Optional(CONF_CLEAR_POWER_OFFSET_CALIBRATION): button.button_schema(
63
+ ATM90E32ClearPowerOffsetCalibrationButton,
64
+ entity_category=ENTITY_CATEGORY_CONFIG,
65
+ icon="mdi:delete",
32
66
  ),
33
67
  }
34
68
 
35
69
 
36
70
  async def to_code(config):
37
71
  parent = await cg.get_variable(config[CONF_ID])
72
+
73
+ if run_gain := config.get(CONF_RUN_GAIN_CALIBRATION):
74
+ b = await button.new_button(run_gain)
75
+ await cg.register_parented(b, parent)
76
+
77
+ if clear_gain := config.get(CONF_CLEAR_GAIN_CALIBRATION):
78
+ b = await button.new_button(clear_gain)
79
+ await cg.register_parented(b, parent)
80
+
38
81
  if run_offset := config.get(CONF_RUN_OFFSET_CALIBRATION):
39
82
  b = await button.new_button(run_offset)
40
83
  await cg.register_parented(b, parent)
84
+
41
85
  if clear_offset := config.get(CONF_CLEAR_OFFSET_CALIBRATION):
42
86
  b = await button.new_button(clear_offset)
43
87
  await cg.register_parented(b, parent)
88
+
89
+ if run_power := config.get(CONF_RUN_POWER_OFFSET_CALIBRATION):
90
+ b = await button.new_button(run_power)
91
+ await cg.register_parented(b, parent)
92
+
93
+ if clear_power := config.get(CONF_CLEAR_POWER_OFFSET_CALIBRATION):
94
+ b = await button.new_button(clear_power)
95
+ await cg.register_parented(b, parent)
@@ -1,4 +1,5 @@
1
1
  #include "atm90e32_button.h"
2
+ #include "esphome/core/component.h"
2
3
  #include "esphome/core/log.h"
3
4
 
4
5
  namespace esphome {
@@ -6,15 +7,73 @@ namespace atm90e32 {
6
7
 
7
8
  static const char *const TAG = "atm90e32.button";
8
9
 
9
- void ATM90E32CalibrationButton::press_action() {
10
- ESP_LOGI(TAG, "Running offset calibrations, Note: CTs and ACVs must be 0 during this process...");
10
+ void ATM90E32GainCalibrationButton::press_action() {
11
+ if (this->parent_ == nullptr) {
12
+ ESP_LOGW(TAG, "[CALIBRATION] No meters assigned to Gain Calibration button [%s]", this->get_name().c_str());
13
+ return;
14
+ }
15
+
16
+ ESP_LOGI(TAG, "%s", this->get_name().c_str());
17
+ ESP_LOGI(TAG,
18
+ "[CALIBRATION] Use gain_ct: & gain_voltage: under each phase_x: in your config file to save these values");
19
+ this->parent_->run_gain_calibrations();
20
+ }
21
+
22
+ void ATM90E32ClearGainCalibrationButton::press_action() {
23
+ if (this->parent_ == nullptr) {
24
+ ESP_LOGW(TAG, "[CALIBRATION] No meters assigned to Clear Gain button [%s]", this->get_name().c_str());
25
+ return;
26
+ }
27
+
28
+ ESP_LOGI(TAG, "%s", this->get_name().c_str());
29
+ this->parent_->clear_gain_calibrations();
30
+ }
31
+
32
+ void ATM90E32OffsetCalibrationButton::press_action() {
33
+ if (this->parent_ == nullptr) {
34
+ ESP_LOGW(TAG, "[CALIBRATION] No meters assigned to Offset Calibration button [%s]", this->get_name().c_str());
35
+ return;
36
+ }
37
+
38
+ ESP_LOGI(TAG, "%s", this->get_name().c_str());
39
+ ESP_LOGI(TAG, "[CALIBRATION] **NOTE: CTs and ACVs must be 0 during this process. USB power only**");
40
+ ESP_LOGI(TAG, "[CALIBRATION] Use offset_voltage: & offset_current: under each phase_x: in your config file to save "
41
+ "these values");
11
42
  this->parent_->run_offset_calibrations();
12
43
  }
13
44
 
14
- void ATM90E32ClearCalibrationButton::press_action() {
15
- ESP_LOGI(TAG, "Offset calibrations cleared.");
45
+ void ATM90E32ClearOffsetCalibrationButton::press_action() {
46
+ if (this->parent_ == nullptr) {
47
+ ESP_LOGW(TAG, "[CALIBRATION] No meters assigned to Clear Offset button [%s]", this->get_name().c_str());
48
+ return;
49
+ }
50
+
51
+ ESP_LOGI(TAG, "%s", this->get_name().c_str());
16
52
  this->parent_->clear_offset_calibrations();
17
53
  }
18
54
 
55
+ void ATM90E32PowerOffsetCalibrationButton::press_action() {
56
+ if (this->parent_ == nullptr) {
57
+ ESP_LOGW(TAG, "[CALIBRATION] No meters assigned to Power Calibration button [%s]", this->get_name().c_str());
58
+ return;
59
+ }
60
+
61
+ ESP_LOGI(TAG, "%s", this->get_name().c_str());
62
+ ESP_LOGI(TAG, "[CALIBRATION] **NOTE: CTs must be 0 during this process. Voltage reference should be present**");
63
+ ESP_LOGI(TAG, "[CALIBRATION] Use offset_active_power: & offset_reactive_power: under each phase_x: in your config "
64
+ "file to save these values");
65
+ this->parent_->run_power_offset_calibrations();
66
+ }
67
+
68
+ void ATM90E32ClearPowerOffsetCalibrationButton::press_action() {
69
+ if (this->parent_ == nullptr) {
70
+ ESP_LOGW(TAG, "[CALIBRATION] No meters assigned to Clear Power button [%s]", this->get_name().c_str());
71
+ return;
72
+ }
73
+
74
+ ESP_LOGI(TAG, "%s", this->get_name().c_str());
75
+ this->parent_->clear_power_offset_calibrations();
76
+ }
77
+
19
78
  } // namespace atm90e32
20
79
  } // namespace esphome
@@ -7,17 +7,49 @@
7
7
  namespace esphome {
8
8
  namespace atm90e32 {
9
9
 
10
- class ATM90E32CalibrationButton : public button::Button, public Parented<ATM90E32Component> {
10
+ class ATM90E32GainCalibrationButton : public button::Button, public Parented<ATM90E32Component> {
11
11
  public:
12
- ATM90E32CalibrationButton() = default;
12
+ ATM90E32GainCalibrationButton() = default;
13
13
 
14
14
  protected:
15
15
  void press_action() override;
16
16
  };
17
17
 
18
- class ATM90E32ClearCalibrationButton : public button::Button, public Parented<ATM90E32Component> {
18
+ class ATM90E32ClearGainCalibrationButton : public button::Button, public Parented<ATM90E32Component> {
19
19
  public:
20
- ATM90E32ClearCalibrationButton() = default;
20
+ ATM90E32ClearGainCalibrationButton() = default;
21
+
22
+ protected:
23
+ void press_action() override;
24
+ };
25
+
26
+ class ATM90E32OffsetCalibrationButton : public button::Button, public Parented<ATM90E32Component> {
27
+ public:
28
+ ATM90E32OffsetCalibrationButton() = default;
29
+
30
+ protected:
31
+ void press_action() override;
32
+ };
33
+
34
+ class ATM90E32ClearOffsetCalibrationButton : public button::Button, public Parented<ATM90E32Component> {
35
+ public:
36
+ ATM90E32ClearOffsetCalibrationButton() = default;
37
+
38
+ protected:
39
+ void press_action() override;
40
+ };
41
+
42
+ class ATM90E32PowerOffsetCalibrationButton : public button::Button, public Parented<ATM90E32Component> {
43
+ public:
44
+ ATM90E32PowerOffsetCalibrationButton() = default;
45
+
46
+ protected:
47
+ void press_action() override;
48
+ };
49
+
50
+ class ATM90E32ClearPowerOffsetCalibrationButton : public button::Button, public Parented<ATM90E32Component> {
51
+ public:
52
+ ATM90E32ClearPowerOffsetCalibrationButton() = default;
21
53
 
22
54
  protected:
23
55
  void press_action() override;
@@ -0,0 +1,130 @@
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_ID,
6
+ CONF_MAX_VALUE,
7
+ CONF_MIN_VALUE,
8
+ CONF_MODE,
9
+ CONF_PHASE_A,
10
+ CONF_PHASE_B,
11
+ CONF_PHASE_C,
12
+ CONF_REFERENCE_VOLTAGE,
13
+ CONF_STEP,
14
+ ENTITY_CATEGORY_CONFIG,
15
+ UNIT_AMPERE,
16
+ UNIT_VOLT,
17
+ )
18
+
19
+ from .. import atm90e32_ns
20
+ from ..sensor import ATM90E32Component
21
+
22
+ ATM90E32Number = atm90e32_ns.class_(
23
+ "ATM90E32Number", number.Number, cg.Parented.template(ATM90E32Component)
24
+ )
25
+
26
+ CONF_REFERENCE_CURRENT = "reference_current"
27
+ PHASE_KEYS = [CONF_PHASE_A, CONF_PHASE_B, CONF_PHASE_C]
28
+
29
+
30
+ REFERENCE_VOLTAGE_PHASE_SCHEMA = cv.All(
31
+ cv.Schema(
32
+ {
33
+ cv.Optional(CONF_MODE, default="box"): cv.string,
34
+ cv.Optional(CONF_MIN_VALUE, default=100.0): cv.float_,
35
+ cv.Optional(CONF_MAX_VALUE, default=260.0): cv.float_,
36
+ cv.Optional(CONF_STEP, default=0.1): cv.float_,
37
+ }
38
+ ).extend(
39
+ number.number_schema(
40
+ class_=ATM90E32Number,
41
+ unit_of_measurement=UNIT_VOLT,
42
+ entity_category=ENTITY_CATEGORY_CONFIG,
43
+ icon="mdi:power-plug",
44
+ )
45
+ )
46
+ )
47
+
48
+
49
+ REFERENCE_CURRENT_PHASE_SCHEMA = cv.All(
50
+ cv.Schema(
51
+ {
52
+ cv.Optional(CONF_MODE, default="box"): cv.string,
53
+ cv.Optional(CONF_MIN_VALUE, default=1.0): cv.float_,
54
+ cv.Optional(CONF_MAX_VALUE, default=200.0): cv.float_,
55
+ cv.Optional(CONF_STEP, default=0.1): cv.float_,
56
+ }
57
+ ).extend(
58
+ number.number_schema(
59
+ class_=ATM90E32Number,
60
+ unit_of_measurement=UNIT_AMPERE,
61
+ entity_category=ENTITY_CATEGORY_CONFIG,
62
+ icon="mdi:home-lightning-bolt",
63
+ )
64
+ )
65
+ )
66
+
67
+
68
+ REFERENCE_VOLTAGE_SCHEMA = cv.Schema(
69
+ {
70
+ cv.Optional(CONF_PHASE_A): REFERENCE_VOLTAGE_PHASE_SCHEMA,
71
+ cv.Optional(CONF_PHASE_B): REFERENCE_VOLTAGE_PHASE_SCHEMA,
72
+ cv.Optional(CONF_PHASE_C): REFERENCE_VOLTAGE_PHASE_SCHEMA,
73
+ }
74
+ )
75
+
76
+ REFERENCE_CURRENT_SCHEMA = cv.Schema(
77
+ {
78
+ cv.Optional(CONF_PHASE_A): REFERENCE_CURRENT_PHASE_SCHEMA,
79
+ cv.Optional(CONF_PHASE_B): REFERENCE_CURRENT_PHASE_SCHEMA,
80
+ cv.Optional(CONF_PHASE_C): REFERENCE_CURRENT_PHASE_SCHEMA,
81
+ }
82
+ )
83
+
84
+ CONFIG_SCHEMA = cv.Schema(
85
+ {
86
+ cv.GenerateID(CONF_ID): cv.use_id(ATM90E32Component),
87
+ cv.Optional(CONF_REFERENCE_VOLTAGE): REFERENCE_VOLTAGE_SCHEMA,
88
+ cv.Optional(CONF_REFERENCE_CURRENT): REFERENCE_CURRENT_SCHEMA,
89
+ }
90
+ )
91
+
92
+
93
+ async def to_code(config):
94
+ parent = await cg.get_variable(config[CONF_ID])
95
+
96
+ if voltage_cfg := config.get(CONF_REFERENCE_VOLTAGE):
97
+ voltage_objs = [None, None, None]
98
+
99
+ for i, key in enumerate(PHASE_KEYS):
100
+ if validated := voltage_cfg.get(key):
101
+ obj = await number.new_number(
102
+ validated,
103
+ min_value=validated["min_value"],
104
+ max_value=validated["max_value"],
105
+ step=validated["step"],
106
+ )
107
+ await cg.register_parented(obj, parent)
108
+ voltage_objs[i] = obj
109
+
110
+ # Inherit from A → B/C if only A defined
111
+ if voltage_objs[0] is not None:
112
+ for i in range(3):
113
+ if voltage_objs[i] is None:
114
+ voltage_objs[i] = voltage_objs[0]
115
+
116
+ for i, obj in enumerate(voltage_objs):
117
+ if obj is not None:
118
+ cg.add(parent.set_reference_voltage(i, obj))
119
+
120
+ if current_cfg := config.get(CONF_REFERENCE_CURRENT):
121
+ for i, key in enumerate(PHASE_KEYS):
122
+ if validated := current_cfg.get(key):
123
+ obj = await number.new_number(
124
+ validated,
125
+ min_value=validated["min_value"],
126
+ max_value=validated["max_value"],
127
+ step=validated["step"],
128
+ )
129
+ await cg.register_parented(obj, parent)
130
+ cg.add(parent.set_reference_current(i, obj))
@@ -0,0 +1,16 @@
1
+ #pragma once
2
+
3
+ #include "esphome/core/component.h"
4
+ #include "esphome/components/atm90e32/atm90e32.h"
5
+ #include "esphome/components/number/number.h"
6
+
7
+ namespace esphome {
8
+ namespace atm90e32 {
9
+
10
+ class ATM90E32Number : public number::Number, public Parented<ATM90E32Component> {
11
+ public:
12
+ void control(float value) override { this->publish_state(value); }
13
+ };
14
+
15
+ } // namespace atm90e32
16
+ } // namespace esphome