esphome 2025.7.4__py3-none-any.whl → 2025.8.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 (758) hide show
  1. esphome/__main__.py +190 -83
  2. esphome/automation.py +2 -4
  3. esphome/build_gen/__init__.py +0 -0
  4. esphome/build_gen/platformio.py +102 -0
  5. esphome/components/a4988/a4988.cpp +0 -1
  6. esphome/components/absolute_humidity/absolute_humidity.cpp +0 -2
  7. esphome/components/absolute_humidity/sensor.py +2 -2
  8. esphome/components/adc/__init__.py +123 -85
  9. esphome/components/adc/adc_sensor.h +98 -35
  10. esphome/components/adc/adc_sensor_common.cpp +10 -4
  11. esphome/components/adc/adc_sensor_esp32.cpp +291 -123
  12. esphome/components/adc/adc_sensor_esp8266.cpp +1 -4
  13. esphome/components/adc/adc_sensor_libretiny.cpp +1 -2
  14. esphome/components/adc/adc_sensor_rp2040.cpp +1 -2
  15. esphome/components/adc/adc_sensor_zephyr.cpp +207 -0
  16. esphome/components/adc/sensor.py +61 -27
  17. esphome/components/adc128s102/adc128s102.cpp +1 -4
  18. esphome/components/ade7880/sensor.py +75 -49
  19. esphome/components/ads1115/ads1115.cpp +0 -1
  20. esphome/components/ads1118/ads1118.cpp +0 -1
  21. esphome/components/ags10/ags10.cpp +0 -4
  22. esphome/components/aht10/aht10.cpp +0 -4
  23. esphome/components/aic3204/aic3204.cpp +0 -2
  24. esphome/components/airthings_wave_plus/__init__.py +1 -1
  25. esphome/components/airthings_wave_plus/airthings_wave_plus.cpp +22 -4
  26. esphome/components/airthings_wave_plus/airthings_wave_plus.h +10 -1
  27. esphome/components/airthings_wave_plus/sensor.py +55 -28
  28. esphome/components/alarm_control_panel/__init__.py +4 -9
  29. esphome/components/am2315c/am2315c.cpp +0 -2
  30. esphome/components/am2320/am2320.cpp +0 -1
  31. esphome/components/animation/__init__.py +14 -11
  32. esphome/components/apds9306/apds9306.cpp +0 -4
  33. esphome/components/apds9960/apds9960.cpp +0 -1
  34. esphome/components/api/__init__.py +29 -4
  35. esphome/components/api/api_connection.cpp +378 -401
  36. esphome/components/api/api_connection.h +112 -56
  37. esphome/components/api/api_frame_helper.cpp +69 -896
  38. esphome/components/api/api_frame_helper.h +31 -126
  39. esphome/components/api/api_frame_helper_noise.cpp +583 -0
  40. esphome/components/api/api_frame_helper_noise.h +68 -0
  41. esphome/components/api/api_frame_helper_plaintext.cpp +290 -0
  42. esphome/components/api/api_frame_helper_plaintext.h +53 -0
  43. esphome/components/api/api_noise_context.h +2 -4
  44. esphome/components/api/api_pb2.cpp +1601 -1808
  45. esphome/components/api/api_pb2.h +367 -323
  46. esphome/components/api/api_pb2_dump.cpp +1137 -3466
  47. esphome/components/api/api_pb2_includes.h +34 -0
  48. esphome/components/api/api_pb2_service.cpp +94 -105
  49. esphome/components/api/api_pb2_service.h +27 -16
  50. esphome/components/api/api_server.cpp +18 -17
  51. esphome/components/api/api_server.h +8 -5
  52. esphome/components/api/client.py +16 -8
  53. esphome/components/api/custom_api_device.h +68 -14
  54. esphome/components/api/homeassistant_service.h +24 -19
  55. esphome/components/api/list_entities.cpp +3 -5
  56. esphome/components/api/list_entities.h +2 -4
  57. esphome/components/api/proto.cpp +3 -5
  58. esphome/components/api/proto.h +239 -274
  59. esphome/components/api/subscribe_state.cpp +2 -4
  60. esphome/components/api/subscribe_state.h +2 -4
  61. esphome/components/api/user_services.cpp +2 -4
  62. esphome/components/api/user_services.h +8 -8
  63. esphome/components/as3935/as3935.cpp +0 -2
  64. esphome/components/as3935_spi/as3935_spi.cpp +0 -2
  65. esphome/components/as5600/__init__.py +1 -1
  66. esphome/components/as5600/as5600.cpp +0 -2
  67. esphome/components/as5600/sensor/__init__.py +0 -1
  68. esphome/components/as7341/as7341.cpp +0 -1
  69. esphome/components/async_tcp/__init__.py +1 -1
  70. esphome/components/at581x/at581x.cpp +1 -1
  71. esphome/components/atm90e26/atm90e26.cpp +0 -1
  72. esphome/components/atm90e32/atm90e32.cpp +475 -116
  73. esphome/components/atm90e32/atm90e32.h +43 -5
  74. esphome/components/audio/audio.h +2 -2
  75. esphome/components/axs15231/touchscreen/axs15231_touchscreen.cpp +0 -2
  76. esphome/components/beken_spi_led_strip/led_strip.cpp +0 -2
  77. esphome/components/bh1750/bh1750.cpp +0 -1
  78. esphome/components/binary_sensor/__init__.py +14 -12
  79. esphome/components/ble_client/__init__.py +4 -7
  80. esphome/components/bluetooth_proxy/__init__.py +40 -3
  81. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +392 -81
  82. esphome/components/bluetooth_proxy/bluetooth_connection.h +16 -5
  83. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +102 -311
  84. esphome/components/bluetooth_proxy/bluetooth_proxy.h +30 -14
  85. esphome/components/bme280_base/bme280_base.cpp +15 -16
  86. esphome/components/bme680/bme680.cpp +2 -3
  87. esphome/components/bme680_bsec/bme680_bsec.cpp +0 -2
  88. esphome/components/bme68x_bsec2/bme68x_bsec2.cpp +0 -2
  89. esphome/components/bmi160/bmi160.cpp +0 -1
  90. esphome/components/bmp085/bmp085.cpp +0 -1
  91. esphome/components/bmp280_base/bmp280_base.cpp +13 -14
  92. esphome/components/bmp3xx_base/bmp3xx_base.cpp +0 -1
  93. esphome/components/bmp581/bmp581.cpp +0 -2
  94. esphome/components/bp1658cj/bp1658cj.cpp +0 -1
  95. esphome/components/bp5758d/bp5758d.cpp +0 -1
  96. esphome/components/button/__init__.py +0 -1
  97. esphome/components/canbus/__init__.py +2 -3
  98. esphome/components/canbus/canbus.cpp +0 -1
  99. esphome/components/cap1188/cap1188.cpp +0 -2
  100. esphome/components/captive_portal/__init__.py +1 -1
  101. esphome/components/cd74hc4067/cd74hc4067.cpp +0 -2
  102. esphome/components/ch422g/ch422g.cpp +0 -1
  103. esphome/components/chsc6x/chsc6x_touchscreen.cpp +0 -3
  104. esphome/components/climate/__init__.py +0 -1
  105. esphome/components/climate/climate_traits.h +24 -0
  106. esphome/components/cm1106/cm1106.cpp +0 -1
  107. esphome/components/const/__init__.py +6 -0
  108. esphome/components/cover/__init__.py +0 -1
  109. esphome/components/cover/cover.cpp +9 -13
  110. esphome/components/cs5460a/cs5460a.cpp +0 -2
  111. esphome/components/cse7761/cse7761.cpp +0 -1
  112. esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +0 -2
  113. esphome/components/cst816/touchscreen/cst816_touchscreen.cpp +0 -2
  114. esphome/components/dac7678/dac7678_output.cpp +0 -2
  115. esphome/components/dallas_temp/dallas_temp.cpp +0 -1
  116. esphome/components/datetime/__init__.py +0 -2
  117. esphome/components/debug/__init__.py +15 -1
  118. esphome/components/debug/debug_zephyr.cpp +281 -0
  119. esphome/components/debug/sensor.py +2 -1
  120. esphome/components/deep_sleep/deep_sleep_component.cpp +0 -1
  121. esphome/components/deep_sleep/deep_sleep_esp32.cpp +20 -1
  122. esphome/components/dfrobot_sen0395/__init__.py +1 -2
  123. esphome/components/dht/dht.cpp +0 -1
  124. esphome/components/dht12/dht12.cpp +0 -1
  125. esphome/components/display/__init__.py +16 -3
  126. esphome/components/display_menu_base/__init__.py +1 -1
  127. esphome/components/dps310/dps310.cpp +0 -2
  128. esphome/components/ds1307/ds1307.cpp +0 -1
  129. esphome/components/ds2484/ds2484.cpp +0 -1
  130. esphome/components/duty_cycle/duty_cycle_sensor.cpp +0 -1
  131. esphome/components/ee895/ee895.cpp +0 -1
  132. esphome/components/ektf2232/touchscreen/ektf2232.cpp +0 -1
  133. esphome/components/emc2101/emc2101.cpp +0 -2
  134. esphome/components/ens160_base/ens160_base.cpp +0 -2
  135. esphome/components/ens210/ens210.cpp +0 -1
  136. esphome/components/es7210/es7210.cpp +0 -2
  137. esphome/components/es7243e/es7243e.cpp +0 -2
  138. esphome/components/es8156/es8156.cpp +0 -2
  139. esphome/components/es8311/es8311.cpp +0 -2
  140. esphome/components/es8388/es8388.cpp +0 -2
  141. esphome/components/esp32/__init__.py +203 -60
  142. esphome/components/esp32/boards.py +17 -0
  143. esphome/components/esp32/gpio.cpp +0 -1
  144. esphome/components/esp32/gpio.py +1 -2
  145. esphome/components/esp32/gpio_esp32_h2.py +2 -7
  146. esphome/components/esp32/gpio_esp32_p4.py +2 -7
  147. esphome/components/esp32/post_build.py.script +112 -61
  148. esphome/components/esp32_ble/__init__.py +41 -2
  149. esphome/components/esp32_ble/ble.cpp +14 -10
  150. esphome/components/esp32_ble/ble.h +18 -18
  151. esphome/components/esp32_ble/ble_advertising.cpp +5 -5
  152. esphome/components/esp32_ble/ble_advertising.h +7 -5
  153. esphome/components/esp32_ble/ble_event.h +139 -73
  154. esphome/components/esp32_ble/ble_scan_result.h +2 -4
  155. esphome/components/esp32_ble/ble_uuid.cpp +5 -5
  156. esphome/components/esp32_ble/ble_uuid.h +6 -5
  157. esphome/components/esp32_ble_beacon/__init__.py +4 -0
  158. esphome/components/esp32_ble_client/__init__.py +1 -1
  159. esphome/components/esp32_ble_client/ble_characteristic.cpp +4 -4
  160. esphome/components/esp32_ble_client/ble_characteristic.h +6 -4
  161. esphome/components/esp32_ble_client/ble_client_base.cpp +155 -104
  162. esphome/components/esp32_ble_client/ble_client_base.h +17 -6
  163. esphome/components/esp32_ble_client/ble_descriptor.h +6 -4
  164. esphome/components/esp32_ble_client/ble_service.cpp +4 -4
  165. esphome/components/esp32_ble_client/ble_service.h +6 -4
  166. esphome/components/esp32_ble_server/__init__.py +15 -12
  167. esphome/components/esp32_ble_tracker/__init__.py +79 -11
  168. esphome/components/esp32_ble_tracker/automation.h +4 -4
  169. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +264 -261
  170. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +103 -37
  171. esphome/components/esp32_camera/__init__.py +13 -1
  172. esphome/components/esp32_camera/esp32_camera.cpp +7 -2
  173. esphome/components/esp32_camera/esp32_camera.h +1 -0
  174. esphome/components/esp32_dac/esp32_dac.cpp +3 -19
  175. esphome/components/esp32_dac/esp32_dac.h +4 -8
  176. esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -6
  177. esphome/components/esp32_rmt_led_strip/light.py +1 -1
  178. esphome/components/esp32_touch/__init__.py +2 -3
  179. esphome/components/esp32_touch/esp32_touch.h +9 -6
  180. esphome/components/esp32_touch/esp32_touch_common.cpp +2 -0
  181. esphome/components/esp32_touch/esp32_touch_v1.cpp +7 -9
  182. esphome/components/esp32_touch/esp32_touch_v2.cpp +10 -6
  183. esphome/components/esp8266/__init__.py +3 -1
  184. esphome/components/esp8266_pwm/esp8266_pwm.cpp +0 -1
  185. esphome/components/esphome/ota/__init__.py +1 -2
  186. esphome/components/esphome/ota/ota_esphome.cpp +150 -77
  187. esphome/components/esphome/ota/ota_esphome.h +8 -1
  188. esphome/components/espnow/__init__.py +309 -0
  189. esphome/components/espnow/automation.h +175 -0
  190. esphome/components/espnow/espnow_component.cpp +468 -0
  191. esphome/components/espnow/espnow_component.h +183 -0
  192. esphome/components/espnow/espnow_err.h +19 -0
  193. esphome/components/espnow/espnow_packet.h +166 -0
  194. esphome/components/ethernet/__init__.py +7 -1
  195. esphome/components/ethernet/esp_eth_phy_jl1101.c +5 -0
  196. esphome/components/ethernet/ethernet_component.cpp +0 -1
  197. esphome/components/ethernet/ethernet_component.h +4 -0
  198. esphome/components/ethernet_info/ethernet_info_text_sensor.h +0 -3
  199. esphome/components/event/__init__.py +0 -1
  200. esphome/components/factory_reset/__init__.py +92 -0
  201. esphome/components/factory_reset/factory_reset.cpp +76 -0
  202. esphome/components/factory_reset/factory_reset.h +43 -0
  203. esphome/components/fan/__init__.py +0 -1
  204. esphome/components/fan/fan_traits.h +16 -0
  205. esphome/components/fastled_base/fastled_light.cpp +0 -1
  206. esphome/components/fastled_spi/light.py +1 -3
  207. esphome/components/fingerprint_grow/fingerprint_grow.cpp +0 -2
  208. esphome/components/font/__init__.py +9 -1
  209. esphome/components/fs3000/fs3000.cpp +0 -2
  210. esphome/components/ft5x06/touchscreen/ft5x06_touchscreen.cpp +0 -2
  211. esphome/components/ft63x6/ft63x6.cpp +0 -1
  212. esphome/components/gdk101/gdk101.cpp +0 -1
  213. esphome/components/gl_r01_i2c/gl_r01_i2c.cpp +0 -1
  214. esphome/components/gl_r01_i2c/sensor.py +1 -1
  215. esphome/components/gpio/one_wire/gpio_one_wire.cpp +0 -1
  216. esphome/components/gpio/switch/gpio_switch.cpp +0 -2
  217. esphome/components/gpio_expander/cached_gpio.h +24 -15
  218. esphome/components/gps/__init__.py +6 -2
  219. esphome/components/gps/gps.cpp +50 -49
  220. esphome/components/gps/gps.h +4 -8
  221. esphome/components/gps/time/gps_time.cpp +3 -9
  222. esphome/components/gps/time/gps_time.h +4 -7
  223. esphome/components/graph/__init__.py +1 -1
  224. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.cpp +0 -1
  225. esphome/components/grove_tb6612fng/grove_tb6612fng.cpp +0 -1
  226. esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +21 -12
  227. esphome/components/gt911/touchscreen/gt911_touchscreen.h +26 -2
  228. esphome/components/haier/climate.py +5 -10
  229. esphome/components/haier/haier_base.cpp +0 -1
  230. esphome/components/hbridge/switch/hbridge_switch.cpp +0 -2
  231. esphome/components/hdc1080/hdc1080.cpp +0 -2
  232. esphome/components/heatpumpir/climate.py +2 -2
  233. esphome/components/hlw8012/hlw8012.cpp +0 -1
  234. esphome/components/hm3301/hm3301.cpp +0 -1
  235. esphome/components/hmc5883l/hmc5883l.cpp +0 -1
  236. esphome/components/homeassistant/__init__.py +1 -0
  237. esphome/components/homeassistant/number/__init__.py +1 -0
  238. esphome/components/homeassistant/number/homeassistant_number.cpp +11 -7
  239. esphome/components/homeassistant/switch/__init__.py +1 -0
  240. esphome/components/homeassistant/switch/homeassistant_switch.cpp +9 -5
  241. esphome/components/honeywellabp/honeywellabp.cpp +1 -4
  242. esphome/components/host/__init__.py +2 -0
  243. esphome/components/hte501/hte501.cpp +0 -1
  244. esphome/components/http_request/__init__.py +2 -3
  245. esphome/components/http_request/http_request_idf.cpp +2 -2
  246. esphome/components/htu21d/htu21d.cpp +0 -2
  247. esphome/components/htu31d/htu31d.cpp +0 -2
  248. esphome/components/hx711/hx711.cpp +0 -1
  249. esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +0 -1
  250. esphome/components/hydreon_rgxx/sensor.py +4 -5
  251. esphome/components/i2c/i2c_bus.h +1 -1
  252. esphome/components/i2c/i2c_bus_arduino.cpp +1 -2
  253. esphome/components/i2c/i2c_bus_esp_idf.cpp +192 -17
  254. esphome/components/i2c/i2c_bus_esp_idf.h +11 -1
  255. esphome/components/i2s_audio/__init__.py +6 -5
  256. esphome/components/i2s_audio/i2s_audio.cpp +0 -2
  257. esphome/components/i2s_audio/media_player/i2s_audio_media_player.cpp +1 -4
  258. esphome/components/i2s_audio/microphone/__init__.py +4 -6
  259. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +46 -19
  260. esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +4 -3
  261. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +273 -269
  262. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +19 -34
  263. esphome/components/ili9xxx/display.py +4 -3
  264. esphome/components/ili9xxx/ili9xxx_display.cpp +0 -2
  265. esphome/components/image/__init__.py +123 -92
  266. esphome/components/improv_serial/__init__.py +7 -8
  267. esphome/components/ina219/ina219.cpp +0 -1
  268. esphome/components/ina226/ina226.cpp +0 -2
  269. esphome/components/ina260/ina260.cpp +0 -2
  270. esphome/components/ina2xx_base/__init__.py +2 -5
  271. esphome/components/ina2xx_base/ina2xx_base.cpp +0 -2
  272. esphome/components/ina3221/ina3221.cpp +0 -1
  273. esphome/components/internal_temperature/internal_temperature.cpp +0 -2
  274. esphome/components/interval/interval.h +5 -9
  275. esphome/components/json/__init__.py +1 -1
  276. esphome/components/kmeteriso/kmeteriso.cpp +0 -2
  277. esphome/components/lc709203f/lc709203f.cpp +0 -2
  278. esphome/components/lcd_gpio/display.py +1 -3
  279. esphome/components/lcd_gpio/gpio_lcd_display.cpp +0 -1
  280. esphome/components/lcd_pcf8574/pcf8574_display.cpp +0 -1
  281. esphome/components/ld2410/__init__.py +4 -6
  282. esphome/components/ld2410/binary_sensor.py +4 -0
  283. esphome/components/ld2410/ld2410.cpp +56 -100
  284. esphome/components/ld2410/ld2410.h +17 -15
  285. esphome/components/ld2410/sensor.py +24 -10
  286. esphome/components/ld2412/__init__.py +46 -0
  287. esphome/components/ld2412/binary_sensor.py +70 -0
  288. esphome/components/ld2412/button/__init__.py +74 -0
  289. esphome/components/ld2412/button/factory_reset_button.cpp +9 -0
  290. esphome/components/ld2412/button/factory_reset_button.h +18 -0
  291. esphome/components/ld2412/button/query_button.cpp +9 -0
  292. esphome/components/ld2412/button/query_button.h +18 -0
  293. esphome/components/ld2412/button/restart_button.cpp +9 -0
  294. esphome/components/ld2412/button/restart_button.h +18 -0
  295. esphome/components/ld2412/button/start_dynamic_background_correction_button.cpp +11 -0
  296. esphome/components/ld2412/button/start_dynamic_background_correction_button.h +18 -0
  297. esphome/components/ld2412/ld2412.cpp +861 -0
  298. esphome/components/ld2412/ld2412.h +141 -0
  299. esphome/components/ld2412/number/__init__.py +126 -0
  300. esphome/components/ld2412/number/gate_threshold_number.cpp +14 -0
  301. esphome/components/ld2412/number/gate_threshold_number.h +19 -0
  302. esphome/components/ld2412/number/light_threshold_number.cpp +12 -0
  303. esphome/components/ld2412/number/light_threshold_number.h +18 -0
  304. esphome/components/ld2412/number/max_distance_timeout_number.cpp +12 -0
  305. esphome/components/ld2412/number/max_distance_timeout_number.h +18 -0
  306. esphome/components/ld2412/select/__init__.py +82 -0
  307. esphome/components/ld2412/select/baud_rate_select.cpp +12 -0
  308. esphome/components/ld2412/select/baud_rate_select.h +18 -0
  309. esphome/components/ld2412/select/distance_resolution_select.cpp +12 -0
  310. esphome/components/ld2412/select/distance_resolution_select.h +18 -0
  311. esphome/components/ld2412/select/light_out_control_select.cpp +12 -0
  312. esphome/components/ld2412/select/light_out_control_select.h +18 -0
  313. esphome/components/ld2412/sensor.py +124 -0
  314. esphome/components/ld2412/switch/__init__.py +45 -0
  315. esphome/components/ld2412/switch/bluetooth_switch.cpp +12 -0
  316. esphome/components/ld2412/switch/bluetooth_switch.h +18 -0
  317. esphome/components/ld2412/switch/engineering_mode_switch.cpp +12 -0
  318. esphome/components/ld2412/switch/engineering_mode_switch.h +18 -0
  319. esphome/components/ld2412/text_sensor.py +34 -0
  320. esphome/components/ld2420/ld2420.cpp +0 -1
  321. esphome/components/ld2450/__init__.py +3 -4
  322. esphome/components/ld2450/binary_sensor.py +3 -0
  323. esphome/components/ld2450/ld2450.cpp +77 -165
  324. esphome/components/ld2450/ld2450.h +26 -54
  325. esphome/components/ld2450/sensor.py +120 -6
  326. esphome/components/ld2450/text_sensor.py +5 -4
  327. esphome/components/ld24xx/__init__.py +1 -0
  328. esphome/components/ld24xx/ld24xx.h +65 -0
  329. esphome/components/ledc/ledc_output.cpp +0 -1
  330. esphome/components/libretiny/__init__.py +2 -0
  331. esphome/components/light/__init__.py +0 -1
  332. esphome/components/light/effects.py +70 -45
  333. esphome/components/light/light_call.cpp +101 -66
  334. esphome/components/light/light_color_values.h +16 -11
  335. esphome/components/light/light_json_schema.cpp +46 -44
  336. esphome/components/light/light_state.cpp +8 -11
  337. esphome/components/light/light_traits.h +17 -0
  338. esphome/components/lightwaverf/lightwaverf.cpp +0 -2
  339. esphome/components/lilygo_t5_47/touchscreen/lilygo_t5_47_touchscreen.cpp +0 -1
  340. esphome/components/lock/__init__.py +0 -1
  341. esphome/components/logger/__init__.py +31 -9
  342. esphome/components/logger/logger.cpp +12 -7
  343. esphome/components/logger/logger.h +25 -14
  344. esphome/components/logger/logger_esp32.cpp +2 -7
  345. esphome/components/logger/logger_esp8266.cpp +2 -4
  346. esphome/components/logger/logger_host.cpp +2 -4
  347. esphome/components/logger/logger_libretiny.cpp +2 -4
  348. esphome/components/logger/logger_rp2040.cpp +2 -4
  349. esphome/components/logger/logger_zephyr.cpp +86 -0
  350. esphome/components/logger/select/logger_level_select.cpp +2 -4
  351. esphome/components/logger/select/logger_level_select.h +2 -4
  352. esphome/components/logger/task_log_buffer.cpp +2 -4
  353. esphome/components/logger/task_log_buffer.h +2 -4
  354. esphome/components/lps22/sensor.py +5 -5
  355. esphome/components/ltr390/ltr390.cpp +0 -2
  356. esphome/components/ltr501/ltr501.cpp +0 -1
  357. esphome/components/ltr_als_ps/ltr_als_ps.cpp +0 -1
  358. esphome/components/lvgl/__init__.py +14 -13
  359. esphome/components/lvgl/automation.py +2 -4
  360. esphome/components/lvgl/defines.py +0 -2
  361. esphome/components/lvgl/helpers.py +1 -1
  362. esphome/components/lvgl/lv_validation.py +7 -4
  363. esphome/components/lvgl/lvgl_esphome.cpp +2 -3
  364. esphome/components/lvgl/styles.py +2 -2
  365. esphome/components/lvgl/types.py +1 -1
  366. esphome/components/lvgl/widgets/__init__.py +2 -2
  367. esphome/components/lvgl/widgets/arc.py +14 -11
  368. esphome/components/lvgl/widgets/buttonmatrix.py +1 -1
  369. esphome/components/lvgl/widgets/qrcode.py +7 -7
  370. esphome/components/lvgl/widgets/spinner.py +6 -6
  371. esphome/components/lvgl/widgets/switch.py +2 -2
  372. esphome/components/lvgl/widgets/tabview.py +3 -3
  373. esphome/components/lvgl/widgets/tileview.py +15 -7
  374. esphome/components/m5stack_8angle/m5stack_8angle.cpp +0 -1
  375. esphome/components/matrix_keypad/__init__.py +4 -3
  376. esphome/components/max17043/max17043.cpp +0 -2
  377. esphome/components/max31855/max31855.cpp +1 -4
  378. esphome/components/max31856/max31856.cpp +0 -4
  379. esphome/components/max31865/max31865.cpp +0 -1
  380. esphome/components/max44009/max44009.cpp +0 -1
  381. esphome/components/max6675/max6675.cpp +1 -4
  382. esphome/components/max6956/max6956.cpp +0 -1
  383. esphome/components/max7219/max7219.cpp +0 -1
  384. esphome/components/max7219digit/display.py +1 -1
  385. esphome/components/max7219digit/max7219digit.cpp +0 -1
  386. esphome/components/max9611/max9611.cpp +0 -1
  387. esphome/components/mcp23008/__init__.py +1 -1
  388. esphome/components/mcp23008/mcp23008.cpp +0 -1
  389. esphome/components/mcp23016/mcp23016.cpp +0 -1
  390. esphome/components/mcp23017/__init__.py +1 -1
  391. esphome/components/mcp23017/mcp23017.cpp +0 -1
  392. esphome/components/mcp23s08/__init__.py +1 -1
  393. esphome/components/mcp23s08/mcp23s08.cpp +0 -1
  394. esphome/components/mcp23s17/__init__.py +1 -1
  395. esphome/components/mcp23s17/mcp23s17.cpp +0 -1
  396. esphome/components/mcp23x08_base/__init__.py +2 -0
  397. esphome/components/mcp23x08_base/mcp23x08_base.cpp +9 -7
  398. esphome/components/mcp23x08_base/mcp23x08_base.h +9 -4
  399. esphome/components/mcp23x17_base/__init__.py +2 -0
  400. esphome/components/mcp23x17_base/mcp23x17_base.cpp +20 -7
  401. esphome/components/mcp23x17_base/mcp23x17_base.h +9 -4
  402. esphome/components/mcp23xxx_base/__init__.py +11 -5
  403. esphome/components/mcp23xxx_base/mcp23xxx_base.cpp +15 -12
  404. esphome/components/mcp23xxx_base/mcp23xxx_base.h +8 -7
  405. esphome/components/mcp3008/mcp3008.cpp +1 -4
  406. esphome/components/mcp3204/mcp3204.cpp +1 -4
  407. esphome/components/mcp4461/mcp4461.cpp +0 -1
  408. esphome/components/mcp4725/mcp4725.cpp +0 -1
  409. esphome/components/mcp4728/mcp4728.cpp +0 -1
  410. esphome/components/mcp9600/mcp9600.cpp +0 -2
  411. esphome/components/mcp9808/mcp9808.cpp +0 -2
  412. esphome/components/mdns/__init__.py +3 -0
  413. esphome/components/mdns/mdns_component.cpp +2 -0
  414. esphome/components/mdns/mdns_component.h +4 -0
  415. esphome/components/media_player/__init__.py +40 -0
  416. esphome/components/media_player/automation.h +16 -0
  417. esphome/components/media_player/media_player.cpp +13 -0
  418. esphome/components/media_player/media_player.h +50 -3
  419. esphome/components/micro_wake_word/micro_wake_word.cpp +0 -3
  420. esphome/components/mics_4514/mics_4514.cpp +1 -6
  421. esphome/components/midea/ir_transmitter.h +4 -4
  422. esphome/components/mipi/__init__.py +416 -0
  423. esphome/components/mipi_dsi/__init__.py +5 -0
  424. esphome/components/mipi_dsi/display.py +233 -0
  425. esphome/components/mipi_dsi/mipi_dsi.cpp +379 -0
  426. esphome/components/mipi_dsi/mipi_dsi.h +123 -0
  427. esphome/components/mipi_dsi/models/__init__.py +0 -0
  428. esphome/components/mipi_dsi/models/guition.py +38 -0
  429. esphome/components/mipi_dsi/models/m5stack.py +57 -0
  430. esphome/components/mipi_dsi/models/waveshare.py +105 -0
  431. esphome/components/mipi_rgb/models/lilygo.py +0 -0
  432. esphome/components/mipi_spi/__init__.py +0 -9
  433. esphome/components/mipi_spi/display.py +220 -256
  434. esphome/components/mipi_spi/mipi_spi.cpp +1 -485
  435. esphome/components/mipi_spi/mipi_spi.h +556 -108
  436. esphome/components/mipi_spi/models/__init__.py +0 -65
  437. esphome/components/mipi_spi/models/adafruit.py +30 -0
  438. esphome/components/mipi_spi/models/amoled.py +41 -5
  439. esphome/components/mipi_spi/models/ili.py +5 -5
  440. esphome/components/mipi_spi/models/jc.py +1 -3
  441. esphome/components/mipi_spi/models/lilygo.py +1 -1
  442. esphome/components/mipi_spi/models/waveshare.py +16 -1
  443. esphome/components/mixer/speaker/__init__.py +4 -5
  444. esphome/components/mlx90393/sensor.py +7 -5
  445. esphome/components/mlx90393/sensor_mlx90393.cpp +0 -1
  446. esphome/components/mlx90614/mlx90614.cpp +0 -1
  447. esphome/components/mmc5603/mmc5603.cpp +0 -1
  448. esphome/components/mmc5983/mmc5983.cpp +0 -2
  449. esphome/components/mpl3115a2/mpl3115a2.cpp +0 -2
  450. esphome/components/mpr121/__init__.py +7 -6
  451. esphome/components/mpr121/mpr121.cpp +0 -1
  452. esphome/components/mpu6050/mpu6050.cpp +0 -1
  453. esphome/components/mpu6886/mpu6886.cpp +0 -1
  454. esphome/components/mqtt/__init__.py +1 -2
  455. esphome/components/mqtt/mqtt_button.cpp +1 -1
  456. esphome/components/mqtt/mqtt_client.cpp +0 -1
  457. esphome/components/mqtt/mqtt_component.cpp +8 -14
  458. esphome/components/mqtt/mqtt_component.h +0 -7
  459. esphome/components/mqtt/mqtt_sensor.cpp +0 -1
  460. esphome/components/mqtt/mqtt_sensor.h +0 -1
  461. esphome/components/mqtt/mqtt_text_sensor.cpp +0 -1
  462. esphome/components/mqtt/mqtt_text_sensor.h +0 -1
  463. esphome/components/ms5611/ms5611.cpp +0 -1
  464. esphome/components/ms8607/ms8607.cpp +0 -1
  465. esphome/components/msa3xx/msa3xx.cpp +0 -2
  466. esphome/components/my9231/my9231.cpp +0 -2
  467. esphome/components/nau7802/nau7802.cpp +0 -1
  468. esphome/components/neopixelbus/light.py +3 -0
  469. esphome/components/network/util.cpp +29 -0
  470. esphome/components/nextion/nextion.cpp +2 -2
  471. esphome/components/nfc/binary_sensor/{binary_sensor.cpp → nfc_binary_sensor.cpp} +1 -1
  472. esphome/components/npi19/npi19.cpp +0 -2
  473. esphome/components/nrf52/__init__.py +223 -0
  474. esphome/components/nrf52/boards.py +34 -0
  475. esphome/components/nrf52/const.py +18 -0
  476. esphome/components/nrf52/gpio.py +79 -0
  477. esphome/components/number/__init__.py +2 -1
  478. esphome/components/one_wire/__init__.py +1 -2
  479. esphome/components/one_wire/one_wire.cpp +0 -2
  480. esphome/components/one_wire/one_wire.h +0 -2
  481. esphome/components/opentherm/hub.cpp +0 -1
  482. esphome/components/opentherm/number/__init__.py +2 -2
  483. esphome/components/openthread/__init__.py +2 -3
  484. esphome/components/openthread/openthread.cpp +30 -13
  485. esphome/components/openthread/openthread.h +3 -0
  486. esphome/components/openthread/openthread_esp.cpp +3 -1
  487. esphome/components/opt3001/sensor.py +2 -6
  488. esphome/components/output/__init__.py +38 -0
  489. esphome/components/output/automation.h +24 -0
  490. esphome/components/output/switch/output_switch.cpp +0 -2
  491. esphome/components/packages/__init__.py +1 -2
  492. esphome/components/packet_transport/__init__.py +4 -3
  493. esphome/components/pca6416a/pca6416a.cpp +0 -1
  494. esphome/components/pca9554/pca9554.cpp +0 -1
  495. esphome/components/pca9685/pca9685_output.cpp +0 -2
  496. esphome/components/pcf85063/pcf85063.cpp +0 -1
  497. esphome/components/pcf8563/pcf8563.cpp +0 -1
  498. esphome/components/pcf8574/pcf8574.cpp +0 -1
  499. esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +0 -1
  500. esphome/components/pipsolar/pipsolar.cpp +54 -42
  501. esphome/components/pipsolar/pipsolar.h +5 -4
  502. esphome/components/pipsolar/sensor/__init__.py +1 -1
  503. esphome/components/pm2005/pm2005.cpp +0 -1
  504. esphome/components/pmsa003i/pmsa003i.cpp +0 -2
  505. esphome/components/pmwcs3/sensor.py +1 -2
  506. esphome/components/pn532/pn532.cpp +0 -2
  507. esphome/components/pn532_spi/pn532_spi.cpp +0 -2
  508. esphome/components/power_supply/power_supply.cpp +7 -10
  509. esphome/components/power_supply/power_supply.h +1 -1
  510. esphome/components/psram/__init__.py +6 -1
  511. esphome/components/pulse_counter/pulse_counter_sensor.cpp +0 -1
  512. esphome/components/pulse_counter/sensor.py +9 -6
  513. esphome/components/pylontech/pylontech.cpp +0 -1
  514. esphome/components/qmc5883l/qmc5883l.cpp +0 -1
  515. esphome/components/qmp6988/qmp6988.cpp +0 -2
  516. esphome/components/qspi_dbi/display.py +2 -3
  517. esphome/components/qspi_dbi/qspi_dbi.cpp +0 -2
  518. esphome/components/qwiic_pir/binary_sensor.py +2 -3
  519. esphome/components/qwiic_pir/qwiic_pir.cpp +0 -2
  520. esphome/components/rc522/rc522.cpp +9 -31
  521. esphome/components/rc522_spi/rc522_spi.cpp +0 -1
  522. esphome/components/remote_base/__init__.py +5 -6
  523. esphome/components/remote_receiver/remote_receiver_esp32.cpp +0 -1
  524. esphome/components/remote_receiver/remote_receiver_esp8266.cpp +0 -1
  525. esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -1
  526. esphome/components/remote_transmitter/__init__.py +26 -0
  527. esphome/components/remote_transmitter/automation.h +18 -0
  528. esphome/components/remote_transmitter/remote_transmitter.h +2 -1
  529. esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +0 -1
  530. esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +2 -0
  531. esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +2 -0
  532. esphome/components/resampler/speaker/__init__.py +4 -5
  533. esphome/components/rf_bridge/__init__.py +4 -8
  534. esphome/components/rotary_encoder/rotary_encoder.cpp +0 -2
  535. esphome/components/rp2040/__init__.py +3 -1
  536. esphome/components/rp2040_pio_led_strip/led_strip.cpp +0 -2
  537. esphome/components/rp2040_pio_led_strip/light.py +1 -2
  538. esphome/components/rp2040_pwm/rp2040_pwm.cpp +1 -5
  539. esphome/components/rpi_dpi_rgb/display.py +13 -15
  540. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +0 -3
  541. esphome/components/runtime_stats/__init__.py +34 -0
  542. esphome/components/runtime_stats/runtime_stats.cpp +102 -0
  543. esphome/components/runtime_stats/runtime_stats.h +132 -0
  544. esphome/components/scd30/scd30.cpp +0 -2
  545. esphome/components/scd30/sensor.py +1 -2
  546. esphome/components/scd4x/scd4x.cpp +0 -1
  547. esphome/components/scd4x/sensor.py +1 -3
  548. esphome/components/sdl/display.py +3 -1
  549. esphome/components/sdl/sdl_esphome.cpp +0 -2
  550. esphome/components/sdp3x/sdp3x.cpp +0 -2
  551. esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.cpp +0 -2
  552. esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp +0 -3
  553. esphome/components/select/__init__.py +2 -3
  554. esphome/components/select/select_traits.cpp +1 -1
  555. esphome/components/select/select_traits.h +1 -1
  556. esphome/components/sen0321/sen0321.cpp +0 -1
  557. esphome/components/sen5x/sen5x.cpp +0 -2
  558. esphome/components/senseair/senseair.cpp +7 -3
  559. esphome/components/senseair/senseair.h +11 -0
  560. esphome/components/sensor/__init__.py +36 -4
  561. esphome/components/sensor/filter.cpp +49 -10
  562. esphome/components/sensor/filter.h +22 -7
  563. esphome/components/sensor/sensor.cpp +0 -1
  564. esphome/components/sensor/sensor.h +0 -9
  565. esphome/components/sfa30/sfa30.cpp +0 -4
  566. esphome/components/sgp30/sgp30.cpp +0 -2
  567. esphome/components/sgp4x/sensor.py +1 -1
  568. esphome/components/sgp4x/sgp4x.cpp +0 -2
  569. esphome/components/shelly_dimmer/shelly_dimmer.cpp +0 -2
  570. esphome/components/sht3xd/sht3xd.cpp +0 -2
  571. esphome/components/sht4x/sht4x.cpp +0 -2
  572. esphome/components/shtcx/shtcx.cpp +0 -1
  573. esphome/components/sim800l/__init__.py +2 -4
  574. esphome/components/sm16716/sm16716.cpp +0 -1
  575. esphome/components/sm2135/sm2135.cpp +0 -1
  576. esphome/components/sm2235/sm2235.cpp +0 -1
  577. esphome/components/sm2335/sm2335.cpp +0 -1
  578. esphome/components/sn74hc165/sn74hc165.cpp +0 -1
  579. esphome/components/sn74hc595/sn74hc595.cpp +0 -1
  580. esphome/components/sntp/sntp_component.cpp +0 -1
  581. esphome/components/sound_level/sensor.py +1 -1
  582. esphome/components/speaker/media_player/__init__.py +21 -33
  583. esphome/components/speaker/media_player/audio_pipeline.cpp +4 -7
  584. esphome/components/spi/__init__.py +29 -13
  585. esphome/components/spi/spi.cpp +0 -2
  586. esphome/components/spi_device/spi_device.cpp +1 -4
  587. esphome/components/sprinkler/__init__.py +4 -4
  588. esphome/components/sps30/sps30.cpp +0 -1
  589. esphome/components/ssd1306_base/__init__.py +11 -11
  590. esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
  591. esphome/components/ssd1306_i2c/ssd1306_i2c.cpp +0 -1
  592. esphome/components/ssd1306_spi/ssd1306_spi.cpp +0 -1
  593. esphome/components/ssd1322_spi/ssd1322_spi.cpp +0 -1
  594. esphome/components/ssd1325_spi/ssd1325_spi.cpp +0 -1
  595. esphome/components/ssd1327_i2c/ssd1327_i2c.cpp +0 -1
  596. esphome/components/ssd1327_spi/ssd1327_spi.cpp +0 -1
  597. esphome/components/ssd1331_spi/ssd1331_spi.cpp +0 -1
  598. esphome/components/ssd1351_spi/ssd1351_spi.cpp +0 -1
  599. esphome/components/st7567_i2c/st7567_i2c.cpp +0 -1
  600. esphome/components/st7567_spi/st7567_spi.cpp +0 -1
  601. esphome/components/st7701s/display.py +10 -14
  602. esphome/components/st7701s/st7701s.cpp +0 -3
  603. esphome/components/st7735/st7735.cpp +0 -1
  604. esphome/components/st7789v/st7789v.cpp +0 -1
  605. esphome/components/st7920/st7920.cpp +0 -1
  606. esphome/components/status_led/light/status_led_light.cpp +0 -2
  607. esphome/components/status_led/status_led.cpp +0 -1
  608. esphome/components/stepper/__init__.py +2 -4
  609. esphome/components/sts3x/sts3x.cpp +0 -1
  610. esphome/components/substitutions/__init__.py +10 -16
  611. esphome/components/substitutions/jinja.py +24 -1
  612. esphome/components/sun/__init__.py +2 -3
  613. esphome/components/switch/__init__.py +31 -1
  614. esphome/components/switch/automation.h +24 -0
  615. esphome/components/switch/switch.cpp +8 -0
  616. esphome/components/switch/switch.h +8 -0
  617. esphome/components/sx126x/sx126x.cpp +0 -2
  618. esphome/components/sx127x/sx127x.cpp +0 -2
  619. esphome/components/sx1509/__init__.py +7 -5
  620. esphome/components/sx1509/output/sx1509_float_output.cpp +1 -1
  621. esphome/components/sx1509/sx1509.cpp +0 -2
  622. esphome/components/syslog/esphome_syslog.cpp +1 -1
  623. esphome/components/tc74/tc74.cpp +0 -1
  624. esphome/components/tca9548a/tca9548a.cpp +0 -1
  625. esphome/components/tca9555/tca9555.cpp +0 -1
  626. esphome/components/tcs34725/tcs34725.cpp +0 -1
  627. esphome/components/tee501/tee501.cpp +0 -1
  628. esphome/components/tem3200/tem3200.cpp +0 -2
  629. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +0 -1
  630. esphome/components/template/cover/template_cover.cpp +0 -1
  631. esphome/components/template/select/template_select.cpp +0 -1
  632. esphome/components/template/text/template_text.cpp +0 -2
  633. esphome/components/template/valve/template_valve.cpp +0 -1
  634. esphome/components/text/__init__.py +0 -1
  635. esphome/components/text/text_traits.h +2 -0
  636. esphome/components/text_sensor/__init__.py +2 -1
  637. esphome/components/text_sensor/text_sensor.cpp +0 -2
  638. esphome/components/text_sensor/text_sensor.h +0 -8
  639. esphome/components/thermostat/climate.py +4 -4
  640. esphome/components/time/__init__.py +7 -4
  641. esphome/components/time/real_time_clock.cpp +16 -3
  642. esphome/components/tlc59208f/tlc59208f_output.cpp +0 -2
  643. esphome/components/tlc5947/tlc5947.cpp +0 -2
  644. esphome/components/tlc5971/tlc5971.cpp +0 -2
  645. esphome/components/tm1621/tm1621.cpp +0 -2
  646. esphome/components/tm1637/tm1637.cpp +0 -2
  647. esphome/components/tm1638/tm1638.cpp +0 -2
  648. esphome/components/tm1651/__init__.py +45 -48
  649. esphome/components/tm1651/tm1651.cpp +213 -47
  650. esphome/components/tm1651/tm1651.h +37 -32
  651. esphome/components/tmp117/tmp117.cpp +0 -2
  652. esphome/components/tsl2561/tsl2561.cpp +0 -1
  653. esphome/components/tsl2591/tsl2591.cpp +0 -1
  654. esphome/components/tt21100/touchscreen/tt21100.cpp +0 -2
  655. esphome/components/ttp229_bsf/ttp229_bsf.cpp +0 -1
  656. esphome/components/ttp229_lsf/ttp229_lsf.cpp +0 -1
  657. esphome/components/tuya/climate/__init__.py +9 -10
  658. esphome/components/tuya/number/__init__.py +8 -6
  659. esphome/components/tx20/tx20.cpp +0 -1
  660. esphome/components/uart/uart_component_esp32_arduino.cpp +0 -1
  661. esphome/components/uart/uart_component_esp8266.cpp +0 -1
  662. esphome/components/uart/uart_component_esp_idf.cpp +0 -2
  663. esphome/components/uart/uart_component_libretiny.cpp +0 -2
  664. esphome/components/uart/uart_component_rp2040.cpp +0 -2
  665. esphome/components/udp/__init__.py +1 -1
  666. esphome/components/ufire_ec/sensor.py +1 -2
  667. esphome/components/ufire_ec/ufire_ec.cpp +0 -2
  668. esphome/components/ufire_ise/sensor.py +1 -2
  669. esphome/components/ufire_ise/ufire_ise.cpp +0 -2
  670. esphome/components/ultrasonic/ultrasonic_sensor.cpp +0 -1
  671. esphome/components/update/__init__.py +0 -1
  672. esphome/components/uptime/sensor/uptime_seconds_sensor.cpp +0 -1
  673. esphome/components/uptime/sensor/uptime_seconds_sensor.h +0 -2
  674. esphome/components/usb_host/usb_host_client.cpp +0 -1
  675. esphome/components/usb_host/usb_host_component.cpp +0 -1
  676. esphome/components/valve/__init__.py +0 -1
  677. esphome/components/veml3235/veml3235.cpp +0 -3
  678. esphome/components/veml7700/veml7700.cpp +0 -2
  679. esphome/components/version/version_text_sensor.cpp +0 -1
  680. esphome/components/version/version_text_sensor.h +0 -1
  681. esphome/components/vl53l0x/vl53l0x_sensor.cpp +0 -4
  682. esphome/components/voice_assistant/voice_assistant.cpp +9 -8
  683. esphome/components/web_server/__init__.py +13 -0
  684. esphome/components/web_server/web_server.cpp +188 -353
  685. esphome/components/web_server/web_server.h +61 -1
  686. esphome/components/web_server_base/__init__.py +1 -1
  687. esphome/components/web_server_base/web_server_base.cpp +2 -0
  688. esphome/components/web_server_base/web_server_base.h +6 -0
  689. esphome/components/web_server_idf/web_server_idf.cpp +10 -8
  690. esphome/components/web_server_idf/web_server_idf.h +2 -0
  691. esphome/components/weikai_i2c/weikai_i2c.cpp +1 -2
  692. esphome/components/weikai_spi/weikai_spi.cpp +1 -1
  693. esphome/components/wifi/__init__.py +17 -43
  694. esphome/components/wifi/wifi_component.cpp +100 -36
  695. esphome/components/wifi/wifi_component.h +5 -1
  696. esphome/components/wifi/wifi_component_esp32_arduino.cpp +30 -0
  697. esphome/components/wifi/wifi_component_esp_idf.cpp +30 -0
  698. esphome/components/wifi_info/wifi_info_text_sensor.h +0 -6
  699. esphome/components/wifi_signal/wifi_signal_sensor.h +0 -1
  700. esphome/components/wireguard/wireguard.cpp +0 -2
  701. esphome/components/x9c/x9c.cpp +0 -2
  702. esphome/components/xgzp68xx/xgzp68xx.cpp +0 -1
  703. esphome/components/xl9535/xl9535.cpp +0 -2
  704. esphome/components/zephyr/__init__.py +252 -0
  705. esphome/components/zephyr/const.py +16 -0
  706. esphome/components/zephyr/core.cpp +90 -0
  707. esphome/components/zephyr/gpio.cpp +120 -0
  708. esphome/components/zephyr/gpio.h +38 -0
  709. esphome/components/zephyr/pre_build.py.script +4 -0
  710. esphome/components/zephyr/preferences.cpp +156 -0
  711. esphome/components/zephyr/preferences.h +13 -0
  712. esphome/config.py +38 -16
  713. esphome/config_helpers.py +1 -2
  714. esphome/config_validation.py +12 -16
  715. esphome/const.py +26 -1
  716. esphome/core/__init__.py +92 -51
  717. esphome/core/application.cpp +75 -21
  718. esphome/core/application.h +106 -171
  719. esphome/core/color.h +10 -0
  720. esphome/core/component.cpp +41 -25
  721. esphome/core/component.h +9 -6
  722. esphome/core/component_iterator.cpp +61 -261
  723. esphome/core/component_iterator.h +15 -0
  724. esphome/core/config.py +26 -11
  725. esphome/core/defines.h +40 -2
  726. esphome/core/entity_base.h +18 -0
  727. esphome/core/entity_helpers.py +45 -10
  728. esphome/core/helpers.cpp +8 -15
  729. esphome/core/helpers.h +60 -6
  730. esphome/core/lock_free_queue.h +1 -1
  731. esphome/core/scheduler.cpp +311 -77
  732. esphome/core/scheduler.h +141 -28
  733. esphome/cpp_generator.py +2 -6
  734. esphome/cpp_helpers.py +1 -1
  735. esphome/dashboard/dashboard.py +2 -3
  736. esphome/dashboard/dns.py +2 -8
  737. esphome/dashboard/web_server.py +34 -19
  738. esphome/espota2.py +1 -4
  739. esphome/git.py +3 -1
  740. esphome/helpers.py +23 -4
  741. esphome/log.py +3 -1
  742. esphome/mqtt.py +3 -5
  743. esphome/platformio_api.py +7 -4
  744. esphome/types.py +12 -0
  745. esphome/util.py +20 -8
  746. esphome/voluptuous_schema.py +4 -3
  747. esphome/vscode.py +1 -2
  748. esphome/wizard.py +1 -4
  749. esphome/writer.py +16 -108
  750. esphome/yaml_util.py +7 -5
  751. {esphome-2025.7.4.dist-info → esphome-2025.8.0.dist-info}/METADATA +13 -14
  752. {esphome-2025.7.4.dist-info → esphome-2025.8.0.dist-info}/RECORD +757 -677
  753. esphome/components/mipi_spi/models/commands.py +0 -82
  754. /esphome/components/nfc/binary_sensor/{binary_sensor.h → nfc_binary_sensor.h} +0 -0
  755. {esphome-2025.7.4.dist-info → esphome-2025.8.0.dist-info}/WHEEL +0 -0
  756. {esphome-2025.7.4.dist-info → esphome-2025.8.0.dist-info}/entry_points.txt +0 -0
  757. {esphome-2025.7.4.dist-info → esphome-2025.8.0.dist-info}/licenses/LICENSE +0 -0
  758. {esphome-2025.7.4.dist-info → esphome-2025.8.0.dist-info}/top_level.txt +0 -0
@@ -109,8 +109,9 @@ void ATM90E32Component::update() {
109
109
  }
110
110
 
111
111
  void ATM90E32Component::setup() {
112
- ESP_LOGCONFIG(TAG, "Running setup");
113
112
  this->spi_setup();
113
+ this->cs_summary_ = this->cs_->dump_summary();
114
+ const char *cs = this->cs_summary_.c_str();
114
115
 
115
116
  uint16_t mmode0 = 0x87; // 3P4W 50Hz
116
117
  uint16_t high_thresh = 0;
@@ -131,9 +132,9 @@ void ATM90E32Component::setup() {
131
132
  mmode0 |= 0 << 1; // sets 1st bit to 0, phase b is not counted into the all-phase sum energy/power (P/Q/S)
132
133
  }
133
134
 
134
- this->write16_(ATM90E32_REGISTER_SOFTRESET, 0x789A); // Perform soft reset
135
- delay(6); // Wait for the minimum 5ms + 1ms
136
- this->write16_(ATM90E32_REGISTER_CFGREGACCEN, 0x55AA); // enable register config access
135
+ this->write16_(ATM90E32_REGISTER_SOFTRESET, 0x789A, false); // Perform soft reset
136
+ delay(6); // Wait for the minimum 5ms + 1ms
137
+ this->write16_(ATM90E32_REGISTER_CFGREGACCEN, 0x55AA); // enable register config access
137
138
  if (!this->validate_spi_read_(0x55AA, "setup()")) {
138
139
  ESP_LOGW(TAG, "Could not initialize ATM90E32 IC, check SPI settings");
139
140
  this->mark_failed();
@@ -157,16 +158,17 @@ void ATM90E32Component::setup() {
157
158
 
158
159
  if (this->enable_offset_calibration_) {
159
160
  // Initialize flash storage for offset calibrations
160
- uint32_t o_hash = fnv1_hash(std::string("_offset_calibration_") + this->cs_->dump_summary());
161
+ uint32_t o_hash = fnv1_hash(std::string("_offset_calibration_") + this->cs_summary_);
161
162
  this->offset_pref_ = global_preferences->make_preference<OffsetCalibration[3]>(o_hash, true);
162
163
  this->restore_offset_calibrations_();
163
164
 
164
165
  // Initialize flash storage for power offset calibrations
165
- uint32_t po_hash = fnv1_hash(std::string("_power_offset_calibration_") + this->cs_->dump_summary());
166
+ uint32_t po_hash = fnv1_hash(std::string("_power_offset_calibration_") + this->cs_summary_);
166
167
  this->power_offset_pref_ = global_preferences->make_preference<PowerOffsetCalibration[3]>(po_hash, true);
167
168
  this->restore_power_offset_calibrations_();
168
169
  } else {
169
- ESP_LOGI(TAG, "[CALIBRATION] Power & Voltage/Current offset calibration is disabled. Using config file values.");
170
+ ESP_LOGI(TAG, "[CALIBRATION][%s] Power & Voltage/Current offset calibration is disabled. Using config file values.",
171
+ cs);
170
172
  for (uint8_t phase = 0; phase < 3; ++phase) {
171
173
  this->write16_(this->voltage_offset_registers[phase],
172
174
  static_cast<uint16_t>(this->offset_phase_[phase].voltage_offset_));
@@ -181,21 +183,18 @@ void ATM90E32Component::setup() {
181
183
 
182
184
  if (this->enable_gain_calibration_) {
183
185
  // Initialize flash storage for gain calibration
184
- uint32_t g_hash = fnv1_hash(std::string("_gain_calibration_") + this->cs_->dump_summary());
186
+ uint32_t g_hash = fnv1_hash(std::string("_gain_calibration_") + this->cs_summary_);
185
187
  this->gain_calibration_pref_ = global_preferences->make_preference<GainCalibration[3]>(g_hash, true);
186
188
  this->restore_gain_calibrations_();
187
189
 
188
- if (this->using_saved_calibrations_) {
189
- ESP_LOGI(TAG, "[CALIBRATION] Successfully restored gain calibration from memory.");
190
- } else {
190
+ if (!this->using_saved_calibrations_) {
191
191
  for (uint8_t phase = 0; phase < 3; ++phase) {
192
192
  this->write16_(voltage_gain_registers[phase], this->phase_[phase].voltage_gain_);
193
193
  this->write16_(current_gain_registers[phase], this->phase_[phase].ct_gain_);
194
194
  }
195
195
  }
196
196
  } else {
197
- ESP_LOGI(TAG, "[CALIBRATION] Gain calibration is disabled. Using config file values.");
198
-
197
+ ESP_LOGI(TAG, "[CALIBRATION][%s] Gain calibration is disabled. Using config file values.", cs);
199
198
  for (uint8_t phase = 0; phase < 3; ++phase) {
200
199
  this->write16_(voltage_gain_registers[phase], this->phase_[phase].voltage_gain_);
201
200
  this->write16_(current_gain_registers[phase], this->phase_[phase].ct_gain_);
@@ -214,6 +213,122 @@ void ATM90E32Component::setup() {
214
213
  this->write16_(ATM90E32_REGISTER_CFGREGACCEN, 0x0000); // end configuration
215
214
  }
216
215
 
216
+ void ATM90E32Component::log_calibration_status_() {
217
+ const char *cs = this->cs_summary_.c_str();
218
+
219
+ bool offset_mismatch = false;
220
+ bool power_mismatch = false;
221
+ bool gain_mismatch = false;
222
+
223
+ for (uint8_t phase = 0; phase < 3; ++phase) {
224
+ offset_mismatch |= this->offset_calibration_mismatch_[phase];
225
+ power_mismatch |= this->power_offset_calibration_mismatch_[phase];
226
+ gain_mismatch |= this->gain_calibration_mismatch_[phase];
227
+ }
228
+
229
+ if (offset_mismatch) {
230
+ ESP_LOGW(TAG, "[CALIBRATION][%s] ", cs);
231
+ ESP_LOGW(TAG,
232
+ "[CALIBRATION][%s] ===================== Offset mismatch: using flash values =====================", cs);
233
+ ESP_LOGW(TAG, "[CALIBRATION][%s] ------------------------------------------------------------------------------",
234
+ cs);
235
+ ESP_LOGW(TAG, "[CALIBRATION][%s] | Phase | offset_voltage | offset_current |", cs);
236
+ ESP_LOGW(TAG, "[CALIBRATION][%s] | | config | flash | config | flash |", cs);
237
+ ESP_LOGW(TAG, "[CALIBRATION][%s] ------------------------------------------------------------------------------",
238
+ cs);
239
+ for (uint8_t phase = 0; phase < 3; ++phase) {
240
+ ESP_LOGW(TAG, "[CALIBRATION][%s] | %c | %6d | %6d | %6d | %6d |", cs, 'A' + phase,
241
+ this->config_offset_phase_[phase].voltage_offset_, this->offset_phase_[phase].voltage_offset_,
242
+ this->config_offset_phase_[phase].current_offset_, this->offset_phase_[phase].current_offset_);
243
+ }
244
+ ESP_LOGW(TAG,
245
+ "[CALIBRATION][%s] ===============================================================================", cs);
246
+ }
247
+ if (power_mismatch) {
248
+ ESP_LOGW(TAG, "[CALIBRATION][%s] ", cs);
249
+ ESP_LOGW(TAG,
250
+ "[CALIBRATION][%s] ================= Power offset mismatch: using flash values =================", cs);
251
+ ESP_LOGW(TAG, "[CALIBRATION][%s] ------------------------------------------------------------------------------",
252
+ cs);
253
+ ESP_LOGW(TAG, "[CALIBRATION][%s] | Phase | offset_active_power|offset_reactive_power|", cs);
254
+ ESP_LOGW(TAG, "[CALIBRATION][%s] | | config | flash | config | flash |", cs);
255
+ ESP_LOGW(TAG, "[CALIBRATION][%s] ------------------------------------------------------------------------------",
256
+ cs);
257
+ for (uint8_t phase = 0; phase < 3; ++phase) {
258
+ ESP_LOGW(TAG, "[CALIBRATION][%s] | %c | %6d | %6d | %6d | %6d |", cs, 'A' + phase,
259
+ this->config_power_offset_phase_[phase].active_power_offset,
260
+ this->power_offset_phase_[phase].active_power_offset,
261
+ this->config_power_offset_phase_[phase].reactive_power_offset,
262
+ this->power_offset_phase_[phase].reactive_power_offset);
263
+ }
264
+ ESP_LOGW(TAG,
265
+ "[CALIBRATION][%s] ===============================================================================", cs);
266
+ }
267
+ if (gain_mismatch) {
268
+ ESP_LOGW(TAG, "[CALIBRATION][%s] ", cs);
269
+ ESP_LOGW(TAG,
270
+ "[CALIBRATION][%s] ====================== Gain mismatch: using flash values =====================", cs);
271
+ ESP_LOGW(TAG, "[CALIBRATION][%s] ------------------------------------------------------------------------------",
272
+ cs);
273
+ ESP_LOGW(TAG, "[CALIBRATION][%s] | Phase | voltage_gain | current_gain |", cs);
274
+ ESP_LOGW(TAG, "[CALIBRATION][%s] | | config | flash | config | flash |", cs);
275
+ ESP_LOGW(TAG, "[CALIBRATION][%s] ------------------------------------------------------------------------------",
276
+ cs);
277
+ for (uint8_t phase = 0; phase < 3; ++phase) {
278
+ ESP_LOGW(TAG, "[CALIBRATION][%s] | %c | %6u | %6u | %6u | %6u |", cs, 'A' + phase,
279
+ this->config_gain_phase_[phase].voltage_gain, this->gain_phase_[phase].voltage_gain,
280
+ this->config_gain_phase_[phase].current_gain, this->gain_phase_[phase].current_gain);
281
+ }
282
+ ESP_LOGW(TAG,
283
+ "[CALIBRATION][%s] ===============================================================================", cs);
284
+ }
285
+ if (!this->enable_offset_calibration_) {
286
+ ESP_LOGI(TAG, "[CALIBRATION][%s] Power & Voltage/Current offset calibration is disabled. Using config file values.",
287
+ cs);
288
+ } else if (this->restored_offset_calibration_ && !offset_mismatch) {
289
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ", cs);
290
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ============== Restored offset calibration from memory ==============", cs);
291
+ ESP_LOGI(TAG, "[CALIBRATION][%s] --------------------------------------------------------------", cs);
292
+ ESP_LOGI(TAG, "[CALIBRATION][%s] | Phase | offset_voltage | offset_current |", cs);
293
+ ESP_LOGI(TAG, "[CALIBRATION][%s] --------------------------------------------------------------", cs);
294
+ for (uint8_t phase = 0; phase < 3; phase++) {
295
+ ESP_LOGI(TAG, "[CALIBRATION][%s] | %c | %6d | %6d |", cs, 'A' + phase,
296
+ this->offset_phase_[phase].voltage_offset_, this->offset_phase_[phase].current_offset_);
297
+ }
298
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ==============================================================\\n", cs);
299
+ }
300
+
301
+ if (this->restored_power_offset_calibration_ && !power_mismatch) {
302
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ", cs);
303
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ============ Restored power offset calibration from memory ============", cs);
304
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ---------------------------------------------------------------------", cs);
305
+ ESP_LOGI(TAG, "[CALIBRATION][%s] | Phase | offset_active_power | offset_reactive_power |", cs);
306
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ---------------------------------------------------------------------", cs);
307
+ for (uint8_t phase = 0; phase < 3; phase++) {
308
+ ESP_LOGI(TAG, "[CALIBRATION][%s] | %c | %6d | %6d |", cs, 'A' + phase,
309
+ this->power_offset_phase_[phase].active_power_offset,
310
+ this->power_offset_phase_[phase].reactive_power_offset);
311
+ }
312
+ ESP_LOGI(TAG, "[CALIBRATION][%s] =====================================================================\n", cs);
313
+ }
314
+ if (!this->enable_gain_calibration_) {
315
+ ESP_LOGI(TAG, "[CALIBRATION][%s] Gain calibration is disabled. Using config file values.", cs);
316
+ } else if (this->restored_gain_calibration_ && !gain_mismatch) {
317
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ", cs);
318
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ============ Restoring saved gain calibrations to registers ============", cs);
319
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ---------------------------------------------------------------------", cs);
320
+ ESP_LOGI(TAG, "[CALIBRATION][%s] | Phase | voltage_gain | current_gain |", cs);
321
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ---------------------------------------------------------------------", cs);
322
+ for (uint8_t phase = 0; phase < 3; phase++) {
323
+ ESP_LOGI(TAG, "[CALIBRATION][%s] | %c | %6u | %6u |", cs, 'A' + phase,
324
+ this->gain_phase_[phase].voltage_gain, this->gain_phase_[phase].current_gain);
325
+ }
326
+ ESP_LOGI(TAG, "[CALIBRATION][%s] =====================================================================\\n", cs);
327
+ ESP_LOGI(TAG, "[CALIBRATION][%s] Gain calibration loaded and verified successfully.\n", cs);
328
+ }
329
+ this->calibration_message_printed_ = true;
330
+ }
331
+
217
332
  void ATM90E32Component::dump_config() {
218
333
  ESP_LOGCONFIG("", "ATM90E32:");
219
334
  LOG_PIN(" CS Pin: ", this->cs_);
@@ -256,6 +371,10 @@ void ATM90E32Component::dump_config() {
256
371
  LOG_SENSOR(" ", "Peak Current C", this->phase_[PHASEC].peak_current_sensor_);
257
372
  LOG_SENSOR(" ", "Frequency", this->freq_sensor_);
258
373
  LOG_SENSOR(" ", "Chip Temp", this->chip_temperature_sensor_);
374
+ if (this->restored_offset_calibration_ || this->restored_power_offset_calibration_ ||
375
+ this->restored_gain_calibration_ || !this->enable_offset_calibration_ || !this->enable_gain_calibration_) {
376
+ this->log_calibration_status_();
377
+ }
259
378
  }
260
379
 
261
380
  float ATM90E32Component::get_setup_priority() const { return setup_priority::IO; }
@@ -264,19 +383,17 @@ float ATM90E32Component::get_setup_priority() const { return setup_priority::IO;
264
383
  // Peakdetect period: 05H. Bit 15:8 are PeakDet_period in ms. 7:0 are Sag_period
265
384
  // Default is 143FH (20ms, 63ms)
266
385
  uint16_t ATM90E32Component::read16_(uint16_t a_register) {
386
+ this->enable();
387
+ delay_microseconds_safe(1); // min delay between CS low and first SCK is 200ns - 1us is plenty
267
388
  uint8_t addrh = (1 << 7) | ((a_register >> 8) & 0x03);
268
389
  uint8_t addrl = (a_register & 0xFF);
269
- uint8_t data[2];
270
- uint16_t output;
271
- this->enable();
272
- delay_microseconds_safe(1); // min delay between CS low and first SCK is 200ns - 1ms is plenty
273
- this->write_byte(addrh);
274
- this->write_byte(addrl);
275
- this->read_array(data, 2);
276
- this->disable();
277
-
278
- output = (uint16_t(data[0] & 0xFF) << 8) | (data[1] & 0xFF);
390
+ uint8_t data[4] = {addrh, addrl, 0x00, 0x00};
391
+ this->transfer_array(data, 4);
392
+ uint16_t output = encode_uint16(data[2], data[3]);
279
393
  ESP_LOGVV(TAG, "read16_ 0x%04" PRIX16 " output 0x%04" PRIX16, a_register, output);
394
+ delay_microseconds_safe(1); // allow the last clock to propagate before releasing CS
395
+ this->disable();
396
+ delay_microseconds_safe(1); // meet minimum CS high time before next transaction
280
397
  return output;
281
398
  }
282
399
 
@@ -293,13 +410,19 @@ int ATM90E32Component::read32_(uint16_t addr_h, uint16_t addr_l) {
293
410
  return val;
294
411
  }
295
412
 
296
- void ATM90E32Component::write16_(uint16_t a_register, uint16_t val) {
413
+ void ATM90E32Component::write16_(uint16_t a_register, uint16_t val, bool validate) {
297
414
  ESP_LOGVV(TAG, "write16_ 0x%04" PRIX16 " val 0x%04" PRIX16, a_register, val);
415
+ uint8_t addrh = ((a_register >> 8) & 0x03);
416
+ uint8_t addrl = (a_register & 0xFF);
417
+ uint8_t data[4] = {addrh, addrl, uint8_t((val >> 8) & 0xFF), uint8_t(val & 0xFF)};
298
418
  this->enable();
299
- this->write_byte16(a_register);
300
- this->write_byte16(val);
419
+ delay_microseconds_safe(1); // ensure CS setup time
420
+ this->write_array(data, 4);
421
+ delay_microseconds_safe(1); // allow clock to settle before raising CS
301
422
  this->disable();
302
- this->validate_spi_read_(val, "write16()");
423
+ delay_microseconds_safe(1); // ensure minimum CS high time
424
+ if (validate)
425
+ this->validate_spi_read_(val, "write16()");
303
426
  }
304
427
 
305
428
  float ATM90E32Component::get_local_phase_voltage_(uint8_t phase) { return this->phase_[phase].voltage_; }
@@ -442,8 +565,10 @@ float ATM90E32Component::get_chip_temperature_() {
442
565
  }
443
566
 
444
567
  void ATM90E32Component::run_gain_calibrations() {
568
+ const char *cs = this->cs_summary_.c_str();
445
569
  if (!this->enable_gain_calibration_) {
446
- ESP_LOGW(TAG, "[CALIBRATION] Gain calibration is disabled! Enable it first with enable_gain_calibration: true");
570
+ ESP_LOGW(TAG, "[CALIBRATION][%s] Gain calibration is disabled! Enable it first with enable_gain_calibration: true",
571
+ cs);
447
572
  return;
448
573
  }
449
574
 
@@ -455,12 +580,14 @@ void ATM90E32Component::run_gain_calibrations() {
455
580
  float ref_currents[3] = {this->get_reference_current(0), this->get_reference_current(1),
456
581
  this->get_reference_current(2)};
457
582
 
458
- ESP_LOGI(TAG, "[CALIBRATION] ");
459
- ESP_LOGI(TAG, "[CALIBRATION] ========================= Gain Calibration =========================");
460
- ESP_LOGI(TAG, "[CALIBRATION] ---------------------------------------------------------------------");
461
- ESP_LOGI(TAG,
462
- "[CALIBRATION] | Phase | V_meas (V) | I_meas (A) | V_ref | I_ref | V_gain (old→new) | I_gain (old→new) |");
463
- ESP_LOGI(TAG, "[CALIBRATION] ---------------------------------------------------------------------");
583
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ", cs);
584
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ========================= Gain Calibration =========================", cs);
585
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ---------------------------------------------------------------------", cs);
586
+ ESP_LOGI(
587
+ TAG,
588
+ "[CALIBRATION][%s] | Phase | V_meas (V) | I_meas (A) | V_ref | I_ref | V_gain (old→new) | I_gain (old→new) |",
589
+ cs);
590
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ---------------------------------------------------------------------", cs);
464
591
 
465
592
  for (uint8_t phase = 0; phase < 3; phase++) {
466
593
  float measured_voltage = this->get_phase_voltage_avg_(phase);
@@ -477,22 +604,22 @@ void ATM90E32Component::run_gain_calibrations() {
477
604
 
478
605
  // Voltage calibration
479
606
  if (ref_voltage <= 0.0f) {
480
- ESP_LOGW(TAG, "[CALIBRATION] Phase %s - Skipping voltage calibration: reference voltage is 0.",
607
+ ESP_LOGW(TAG, "[CALIBRATION][%s] Phase %s - Skipping voltage calibration: reference voltage is 0.", cs,
481
608
  phase_labels[phase]);
482
609
  } else if (measured_voltage == 0.0f) {
483
- ESP_LOGW(TAG, "[CALIBRATION] Phase %s - Skipping voltage calibration: measured voltage is 0.",
610
+ ESP_LOGW(TAG, "[CALIBRATION][%s] Phase %s - Skipping voltage calibration: measured voltage is 0.", cs,
484
611
  phase_labels[phase]);
485
612
  } else {
486
613
  uint32_t new_voltage_gain = static_cast<uint16_t>((ref_voltage / measured_voltage) * current_voltage_gain);
487
614
  if (new_voltage_gain == 0) {
488
- ESP_LOGW(TAG, "[CALIBRATION] Phase %s - Voltage gain would be 0. Check reference and measured voltage.",
615
+ ESP_LOGW(TAG, "[CALIBRATION][%s] Phase %s - Voltage gain would be 0. Check reference and measured voltage.", cs,
489
616
  phase_labels[phase]);
490
617
  } else {
491
618
  if (new_voltage_gain >= 65535) {
492
- ESP_LOGW(
493
- TAG,
494
- "[CALIBRATION] Phase %s - Voltage gain exceeds 65535. You may need a higher output voltage transformer.",
495
- phase_labels[phase]);
619
+ ESP_LOGW(TAG,
620
+ "[CALIBRATION][%s] Phase %s - Voltage gain exceeds 65535. You may need a higher output voltage "
621
+ "transformer.",
622
+ cs, phase_labels[phase]);
496
623
  new_voltage_gain = 65535;
497
624
  }
498
625
  this->gain_phase_[phase].voltage_gain = static_cast<uint16_t>(new_voltage_gain);
@@ -502,20 +629,20 @@ void ATM90E32Component::run_gain_calibrations() {
502
629
 
503
630
  // Current calibration
504
631
  if (ref_current == 0.0f) {
505
- ESP_LOGW(TAG, "[CALIBRATION] Phase %s - Skipping current calibration: reference current is 0.",
632
+ ESP_LOGW(TAG, "[CALIBRATION][%s] Phase %s - Skipping current calibration: reference current is 0.", cs,
506
633
  phase_labels[phase]);
507
634
  } else if (measured_current == 0.0f) {
508
- ESP_LOGW(TAG, "[CALIBRATION] Phase %s - Skipping current calibration: measured current is 0.",
635
+ ESP_LOGW(TAG, "[CALIBRATION][%s] Phase %s - Skipping current calibration: measured current is 0.", cs,
509
636
  phase_labels[phase]);
510
637
  } else {
511
638
  uint32_t new_current_gain = static_cast<uint16_t>((ref_current / measured_current) * current_current_gain);
512
639
  if (new_current_gain == 0) {
513
- ESP_LOGW(TAG, "[CALIBRATION] Phase %s - Current gain would be 0. Check reference and measured current.",
640
+ ESP_LOGW(TAG, "[CALIBRATION][%s] Phase %s - Current gain would be 0. Check reference and measured current.", cs,
514
641
  phase_labels[phase]);
515
642
  } else {
516
643
  if (new_current_gain >= 65535) {
517
- ESP_LOGW(TAG, "[CALIBRATION] Phase %s - Current gain exceeds 65535. You may need to turn up pga gain.",
518
- phase_labels[phase]);
644
+ ESP_LOGW(TAG, "[CALIBRATION][%s] Phase %s - Current gain exceeds 65535. You may need to turn up pga gain.",
645
+ cs, phase_labels[phase]);
519
646
  new_current_gain = 65535;
520
647
  }
521
648
  this->gain_phase_[phase].current_gain = static_cast<uint16_t>(new_current_gain);
@@ -524,13 +651,13 @@ void ATM90E32Component::run_gain_calibrations() {
524
651
  }
525
652
 
526
653
  // Final row output
527
- ESP_LOGI(TAG, "[CALIBRATION] | %c | %9.2f | %9.4f | %5.2f | %6.4f | %5u → %-5u | %5u → %-5u |",
654
+ ESP_LOGI(TAG, "[CALIBRATION][%s] | %c | %9.2f | %9.4f | %5.2f | %6.4f | %5u → %-5u | %5u → %-5u |", cs,
528
655
  'A' + phase, measured_voltage, measured_current, ref_voltage, ref_current, current_voltage_gain,
529
656
  did_voltage ? this->gain_phase_[phase].voltage_gain : current_voltage_gain, current_current_gain,
530
657
  did_current ? this->gain_phase_[phase].current_gain : current_current_gain);
531
658
  }
532
659
 
533
- ESP_LOGI(TAG, "[CALIBRATION] =====================================================================\n");
660
+ ESP_LOGI(TAG, "[CALIBRATION][%s] =====================================================================\n", cs);
534
661
 
535
662
  this->save_gain_calibration_to_memory_();
536
663
  this->write_gains_to_registers_();
@@ -538,54 +665,108 @@ void ATM90E32Component::run_gain_calibrations() {
538
665
  }
539
666
 
540
667
  void ATM90E32Component::save_gain_calibration_to_memory_() {
668
+ const char *cs = this->cs_summary_.c_str();
541
669
  bool success = this->gain_calibration_pref_.save(&this->gain_phase_);
670
+ global_preferences->sync();
671
+ if (success) {
672
+ this->using_saved_calibrations_ = true;
673
+ ESP_LOGI(TAG, "[CALIBRATION][%s] Gain calibration saved to memory.", cs);
674
+ } else {
675
+ this->using_saved_calibrations_ = false;
676
+ ESP_LOGE(TAG, "[CALIBRATION][%s] Failed to save gain calibration to memory!", cs);
677
+ }
678
+ }
679
+
680
+ void ATM90E32Component::save_offset_calibration_to_memory_() {
681
+ const char *cs = this->cs_summary_.c_str();
682
+ bool success = this->offset_pref_.save(&this->offset_phase_);
683
+ global_preferences->sync();
684
+ if (success) {
685
+ this->using_saved_calibrations_ = true;
686
+ this->restored_offset_calibration_ = true;
687
+ for (bool &phase : this->offset_calibration_mismatch_)
688
+ phase = false;
689
+ ESP_LOGI(TAG, "[CALIBRATION][%s] Offset calibration saved to memory.", cs);
690
+ } else {
691
+ this->using_saved_calibrations_ = false;
692
+ ESP_LOGE(TAG, "[CALIBRATION][%s] Failed to save offset calibration to memory!", cs);
693
+ }
694
+ }
695
+
696
+ void ATM90E32Component::save_power_offset_calibration_to_memory_() {
697
+ const char *cs = this->cs_summary_.c_str();
698
+ bool success = this->power_offset_pref_.save(&this->power_offset_phase_);
699
+ global_preferences->sync();
542
700
  if (success) {
543
701
  this->using_saved_calibrations_ = true;
544
- ESP_LOGI(TAG, "[CALIBRATION] Gain calibration saved to memory.");
702
+ this->restored_power_offset_calibration_ = true;
703
+ for (bool &phase : this->power_offset_calibration_mismatch_)
704
+ phase = false;
705
+ ESP_LOGI(TAG, "[CALIBRATION][%s] Power offset calibration saved to memory.", cs);
545
706
  } else {
546
707
  this->using_saved_calibrations_ = false;
547
- ESP_LOGE(TAG, "[CALIBRATION] Failed to save gain calibration to memory!");
708
+ ESP_LOGE(TAG, "[CALIBRATION][%s] Failed to save power offset calibration to memory!", cs);
548
709
  }
549
710
  }
550
711
 
551
712
  void ATM90E32Component::run_offset_calibrations() {
713
+ const char *cs = this->cs_summary_.c_str();
552
714
  if (!this->enable_offset_calibration_) {
553
- ESP_LOGW(TAG, "[CALIBRATION] Offset calibration is disabled! Enable it first with enable_offset_calibration: true");
715
+ ESP_LOGW(TAG,
716
+ "[CALIBRATION][%s] Offset calibration is disabled! Enable it first with enable_offset_calibration: true",
717
+ cs);
554
718
  return;
555
719
  }
556
720
 
721
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ", cs);
722
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ======================== Offset Calibration ========================", cs);
723
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ------------------------------------------------------------------", cs);
724
+ ESP_LOGI(TAG, "[CALIBRATION][%s] | Phase | offset_voltage | offset_current |", cs);
725
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ------------------------------------------------------------------", cs);
726
+
557
727
  for (uint8_t phase = 0; phase < 3; phase++) {
558
728
  int16_t voltage_offset = calibrate_offset(phase, true);
559
729
  int16_t current_offset = calibrate_offset(phase, false);
560
730
 
561
731
  this->write_offsets_to_registers_(phase, voltage_offset, current_offset);
562
732
 
563
- ESP_LOGI(TAG, "[CALIBRATION] Phase %c - offset_voltage: %d, offset_current: %d", 'A' + phase, voltage_offset,
733
+ ESP_LOGI(TAG, "[CALIBRATION][%s] | %c | %6d | %6d |", cs, 'A' + phase, voltage_offset,
564
734
  current_offset);
565
735
  }
566
736
 
567
- this->offset_pref_.save(&this->offset_phase_); // Save to flash
737
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ==================================================================\n", cs);
738
+
739
+ this->save_offset_calibration_to_memory_();
568
740
  }
569
741
 
570
742
  void ATM90E32Component::run_power_offset_calibrations() {
743
+ const char *cs = this->cs_summary_.c_str();
571
744
  if (!this->enable_offset_calibration_) {
572
745
  ESP_LOGW(
573
746
  TAG,
574
- "[CALIBRATION] Offset power calibration is disabled! Enable it first with enable_offset_calibration: true");
747
+ "[CALIBRATION][%s] Offset power calibration is disabled! Enable it first with enable_offset_calibration: true",
748
+ cs);
575
749
  return;
576
750
  }
577
751
 
752
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ", cs);
753
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ===================== Power Offset Calibration =====================", cs);
754
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ---------------------------------------------------------------------", cs);
755
+ ESP_LOGI(TAG, "[CALIBRATION][%s] | Phase | offset_active_power | offset_reactive_power |", cs);
756
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ---------------------------------------------------------------------", cs);
757
+
578
758
  for (uint8_t phase = 0; phase < 3; ++phase) {
579
759
  int16_t active_offset = calibrate_power_offset(phase, false);
580
760
  int16_t reactive_offset = calibrate_power_offset(phase, true);
581
761
 
582
762
  this->write_power_offsets_to_registers_(phase, active_offset, reactive_offset);
583
763
 
584
- ESP_LOGI(TAG, "[CALIBRATION] Phase %c - offset_active_power: %d, offset_reactive_power: %d", 'A' + phase,
585
- active_offset, reactive_offset);
764
+ ESP_LOGI(TAG, "[CALIBRATION][%s] | %c | %6d | %6d |", cs, 'A' + phase, active_offset,
765
+ reactive_offset);
586
766
  }
767
+ ESP_LOGI(TAG, "[CALIBRATION][%s] =====================================================================\n", cs);
587
768
 
588
- this->power_offset_pref_.save(&this->power_offset_phase_); // Save to flash
769
+ this->save_power_offset_calibration_to_memory_();
589
770
  }
590
771
 
591
772
  void ATM90E32Component::write_gains_to_registers_() {
@@ -632,102 +813,276 @@ void ATM90E32Component::write_power_offsets_to_registers_(uint8_t phase, int16_t
632
813
  }
633
814
 
634
815
  void ATM90E32Component::restore_gain_calibrations_() {
635
- if (this->gain_calibration_pref_.load(&this->gain_phase_)) {
636
- ESP_LOGI(TAG, "[CALIBRATION] Restoring saved gain calibrations to registers:");
816
+ const char *cs = this->cs_summary_.c_str();
817
+ for (uint8_t i = 0; i < 3; ++i) {
818
+ this->config_gain_phase_[i].voltage_gain = this->phase_[i].voltage_gain_;
819
+ this->config_gain_phase_[i].current_gain = this->phase_[i].ct_gain_;
820
+ this->gain_phase_[i] = this->config_gain_phase_[i];
821
+ }
637
822
 
638
- for (uint8_t phase = 0; phase < 3; phase++) {
639
- uint16_t v_gain = this->gain_phase_[phase].voltage_gain;
640
- uint16_t i_gain = this->gain_phase_[phase].current_gain;
641
- ESP_LOGI(TAG, "[CALIBRATION] Phase %c - Voltage Gain: %u, Current Gain: %u", 'A' + phase, v_gain, i_gain);
823
+ if (this->gain_calibration_pref_.load(&this->gain_phase_)) {
824
+ bool all_zero = true;
825
+ bool same_as_config = true;
826
+ for (uint8_t phase = 0; phase < 3; ++phase) {
827
+ const auto &cfg = this->config_gain_phase_[phase];
828
+ const auto &saved = this->gain_phase_[phase];
829
+ if (saved.voltage_gain != 0 || saved.current_gain != 0)
830
+ all_zero = false;
831
+ if (saved.voltage_gain != cfg.voltage_gain || saved.current_gain != cfg.current_gain)
832
+ same_as_config = false;
642
833
  }
643
834
 
644
- this->write_gains_to_registers_();
835
+ if (!all_zero && !same_as_config) {
836
+ for (uint8_t phase = 0; phase < 3; ++phase) {
837
+ bool mismatch = false;
838
+ if (this->has_config_voltage_gain_[phase] &&
839
+ this->gain_phase_[phase].voltage_gain != this->config_gain_phase_[phase].voltage_gain)
840
+ mismatch = true;
841
+ if (this->has_config_current_gain_[phase] &&
842
+ this->gain_phase_[phase].current_gain != this->config_gain_phase_[phase].current_gain)
843
+ mismatch = true;
844
+ if (mismatch)
845
+ this->gain_calibration_mismatch_[phase] = true;
846
+ }
847
+
848
+ this->write_gains_to_registers_();
849
+
850
+ if (this->verify_gain_writes_()) {
851
+ this->using_saved_calibrations_ = true;
852
+ this->restored_gain_calibration_ = true;
853
+ return;
854
+ }
645
855
 
646
- if (this->verify_gain_writes_()) {
647
- this->using_saved_calibrations_ = true;
648
- ESP_LOGI(TAG, "[CALIBRATION] Gain calibration loaded and verified successfully.");
649
- } else {
650
856
  this->using_saved_calibrations_ = false;
651
- ESP_LOGE(TAG, "[CALIBRATION] Gain verification failed! Calibration may not be applied correctly.");
857
+ ESP_LOGE(TAG, "[CALIBRATION][%s] Gain verification failed! Calibration may not be applied correctly.", cs);
652
858
  }
653
- } else {
654
- this->using_saved_calibrations_ = false;
655
- ESP_LOGW(TAG, "[CALIBRATION] No stored gain calibrations found. Using config file values.");
656
859
  }
860
+
861
+ this->using_saved_calibrations_ = false;
862
+ for (uint8_t i = 0; i < 3; ++i)
863
+ this->gain_phase_[i] = this->config_gain_phase_[i];
864
+ this->write_gains_to_registers_();
865
+
866
+ ESP_LOGW(TAG, "[CALIBRATION][%s] No stored gain calibrations found. Using config file values.", cs);
657
867
  }
658
868
 
659
869
  void ATM90E32Component::restore_offset_calibrations_() {
660
- if (this->offset_pref_.load(&this->offset_phase_)) {
661
- ESP_LOGI(TAG, "[CALIBRATION] Successfully restored offset calibration from memory.");
870
+ const char *cs = this->cs_summary_.c_str();
871
+ for (uint8_t i = 0; i < 3; ++i)
872
+ this->config_offset_phase_[i] = this->offset_phase_[i];
873
+
874
+ bool have_data = this->offset_pref_.load(&this->offset_phase_);
875
+ bool all_zero = true;
876
+ if (have_data) {
877
+ for (auto &phase : this->offset_phase_) {
878
+ if (phase.voltage_offset_ != 0 || phase.current_offset_ != 0) {
879
+ all_zero = false;
880
+ break;
881
+ }
882
+ }
883
+ }
662
884
 
885
+ if (have_data && !all_zero) {
886
+ this->restored_offset_calibration_ = true;
663
887
  for (uint8_t phase = 0; phase < 3; phase++) {
664
888
  auto &offset = this->offset_phase_[phase];
665
- write_offsets_to_registers_(phase, offset.voltage_offset_, offset.current_offset_);
666
- ESP_LOGI(TAG, "[CALIBRATION] Phase %c - offset_voltage:: %d, offset_current: %d", 'A' + phase,
667
- offset.voltage_offset_, offset.current_offset_);
889
+ bool mismatch = false;
890
+ if (this->has_config_voltage_offset_[phase] &&
891
+ offset.voltage_offset_ != this->config_offset_phase_[phase].voltage_offset_)
892
+ mismatch = true;
893
+ if (this->has_config_current_offset_[phase] &&
894
+ offset.current_offset_ != this->config_offset_phase_[phase].current_offset_)
895
+ mismatch = true;
896
+ if (mismatch)
897
+ this->offset_calibration_mismatch_[phase] = true;
668
898
  }
669
899
  } else {
670
- ESP_LOGW(TAG, "[CALIBRATION] No stored offset calibrations found. Using default values.");
900
+ for (uint8_t phase = 0; phase < 3; phase++)
901
+ this->offset_phase_[phase] = this->config_offset_phase_[phase];
902
+ ESP_LOGW(TAG, "[CALIBRATION][%s] No stored offset calibrations found. Using default values.", cs);
903
+ }
904
+
905
+ for (uint8_t phase = 0; phase < 3; phase++) {
906
+ write_offsets_to_registers_(phase, this->offset_phase_[phase].voltage_offset_,
907
+ this->offset_phase_[phase].current_offset_);
671
908
  }
672
909
  }
673
910
 
674
911
  void ATM90E32Component::restore_power_offset_calibrations_() {
675
- if (this->power_offset_pref_.load(&this->power_offset_phase_)) {
676
- ESP_LOGI(TAG, "[CALIBRATION] Successfully restored power offset calibration from memory.");
912
+ const char *cs = this->cs_summary_.c_str();
913
+ for (uint8_t i = 0; i < 3; ++i)
914
+ this->config_power_offset_phase_[i] = this->power_offset_phase_[i];
915
+
916
+ bool have_data = this->power_offset_pref_.load(&this->power_offset_phase_);
917
+ bool all_zero = true;
918
+ if (have_data) {
919
+ for (auto &phase : this->power_offset_phase_) {
920
+ if (phase.active_power_offset != 0 || phase.reactive_power_offset != 0) {
921
+ all_zero = false;
922
+ break;
923
+ }
924
+ }
925
+ }
677
926
 
927
+ if (have_data && !all_zero) {
928
+ this->restored_power_offset_calibration_ = true;
678
929
  for (uint8_t phase = 0; phase < 3; ++phase) {
679
930
  auto &offset = this->power_offset_phase_[phase];
680
- write_power_offsets_to_registers_(phase, offset.active_power_offset, offset.reactive_power_offset);
681
- ESP_LOGI(TAG, "[CALIBRATION] Phase %c - offset_active_power: %d, offset_reactive_power: %d", 'A' + phase,
682
- offset.active_power_offset, offset.reactive_power_offset);
931
+ bool mismatch = false;
932
+ if (this->has_config_active_power_offset_[phase] &&
933
+ offset.active_power_offset != this->config_power_offset_phase_[phase].active_power_offset)
934
+ mismatch = true;
935
+ if (this->has_config_reactive_power_offset_[phase] &&
936
+ offset.reactive_power_offset != this->config_power_offset_phase_[phase].reactive_power_offset)
937
+ mismatch = true;
938
+ if (mismatch)
939
+ this->power_offset_calibration_mismatch_[phase] = true;
683
940
  }
684
941
  } else {
685
- ESP_LOGW(TAG, "[CALIBRATION] No stored power offsets found. Using default values.");
942
+ for (uint8_t phase = 0; phase < 3; ++phase)
943
+ this->power_offset_phase_[phase] = this->config_power_offset_phase_[phase];
944
+ ESP_LOGW(TAG, "[CALIBRATION][%s] No stored power offsets found. Using default values.", cs);
945
+ }
946
+
947
+ for (uint8_t phase = 0; phase < 3; ++phase) {
948
+ write_power_offsets_to_registers_(phase, this->power_offset_phase_[phase].active_power_offset,
949
+ this->power_offset_phase_[phase].reactive_power_offset);
686
950
  }
687
951
  }
688
952
 
689
953
  void ATM90E32Component::clear_gain_calibrations() {
690
- ESP_LOGI(TAG, "[CALIBRATION] Clearing stored gain calibrations and restoring config-defined values");
954
+ const char *cs = this->cs_summary_.c_str();
955
+ if (!this->using_saved_calibrations_) {
956
+ ESP_LOGI(TAG, "[CALIBRATION][%s] No stored gain calibrations to clear. Current values:", cs);
957
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ----------------------------------------------------------", cs);
958
+ ESP_LOGI(TAG, "[CALIBRATION][%s] | Phase | voltage_gain | current_gain |", cs);
959
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ----------------------------------------------------------", cs);
960
+ for (int phase = 0; phase < 3; phase++) {
961
+ ESP_LOGI(TAG, "[CALIBRATION][%s] | %c | %6u | %6u |", cs, 'A' + phase,
962
+ this->gain_phase_[phase].voltage_gain, this->gain_phase_[phase].current_gain);
963
+ }
964
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ==========================================================\n", cs);
965
+ return;
966
+ }
967
+
968
+ ESP_LOGI(TAG, "[CALIBRATION][%s] Clearing stored gain calibrations and restoring config-defined values", cs);
969
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ----------------------------------------------------------", cs);
970
+ ESP_LOGI(TAG, "[CALIBRATION][%s] | Phase | voltage_gain | current_gain |", cs);
971
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ----------------------------------------------------------", cs);
691
972
 
692
973
  for (int phase = 0; phase < 3; phase++) {
693
- gain_phase_[phase].voltage_gain = this->phase_[phase].voltage_gain_;
694
- gain_phase_[phase].current_gain = this->phase_[phase].ct_gain_;
974
+ uint16_t voltage_gain = this->phase_[phase].voltage_gain_;
975
+ uint16_t current_gain = this->phase_[phase].ct_gain_;
976
+
977
+ this->config_gain_phase_[phase].voltage_gain = voltage_gain;
978
+ this->config_gain_phase_[phase].current_gain = current_gain;
979
+ this->gain_phase_[phase].voltage_gain = voltage_gain;
980
+ this->gain_phase_[phase].current_gain = current_gain;
981
+
982
+ ESP_LOGI(TAG, "[CALIBRATION][%s] | %c | %6u | %6u |", cs, 'A' + phase, voltage_gain, current_gain);
695
983
  }
984
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ==========================================================\n", cs);
985
+
986
+ GainCalibration zero_gains[3]{{0, 0}, {0, 0}, {0, 0}};
987
+ bool success = this->gain_calibration_pref_.save(&zero_gains);
988
+ global_preferences->sync();
696
989
 
697
- bool success = this->gain_calibration_pref_.save(&this->gain_phase_);
698
990
  this->using_saved_calibrations_ = false;
991
+ this->restored_gain_calibration_ = false;
992
+ for (bool &phase : this->gain_calibration_mismatch_)
993
+ phase = false;
699
994
 
700
- if (success) {
701
- ESP_LOGI(TAG, "[CALIBRATION] Gain calibrations cleared. Config values restored:");
702
- for (int phase = 0; phase < 3; phase++) {
703
- ESP_LOGI(TAG, "[CALIBRATION] Phase %c - Voltage Gain: %u, Current Gain: %u", 'A' + phase,
704
- gain_phase_[phase].voltage_gain, gain_phase_[phase].current_gain);
705
- }
706
- } else {
707
- ESP_LOGE(TAG, "[CALIBRATION] Failed to clear gain calibrations!");
995
+ if (!success) {
996
+ ESP_LOGE(TAG, "[CALIBRATION][%s] Failed to clear gain calibrations!", cs);
708
997
  }
709
998
 
710
999
  this->write_gains_to_registers_(); // Apply them to the chip immediately
711
1000
  }
712
1001
 
713
1002
  void ATM90E32Component::clear_offset_calibrations() {
1003
+ const char *cs = this->cs_summary_.c_str();
1004
+ if (!this->restored_offset_calibration_) {
1005
+ ESP_LOGI(TAG, "[CALIBRATION][%s] No stored offset calibrations to clear. Current values:", cs);
1006
+ ESP_LOGI(TAG, "[CALIBRATION][%s] --------------------------------------------------------------", cs);
1007
+ ESP_LOGI(TAG, "[CALIBRATION][%s] | Phase | offset_voltage | offset_current |", cs);
1008
+ ESP_LOGI(TAG, "[CALIBRATION][%s] --------------------------------------------------------------", cs);
1009
+ for (uint8_t phase = 0; phase < 3; phase++) {
1010
+ ESP_LOGI(TAG, "[CALIBRATION][%s] | %c | %6d | %6d |", cs, 'A' + phase,
1011
+ this->offset_phase_[phase].voltage_offset_, this->offset_phase_[phase].current_offset_);
1012
+ }
1013
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ==============================================================\n", cs);
1014
+ return;
1015
+ }
1016
+
1017
+ ESP_LOGI(TAG, "[CALIBRATION][%s] Clearing stored offset calibrations and restoring config-defined values", cs);
1018
+ ESP_LOGI(TAG, "[CALIBRATION][%s] --------------------------------------------------------------", cs);
1019
+ ESP_LOGI(TAG, "[CALIBRATION][%s] | Phase | offset_voltage | offset_current |", cs);
1020
+ ESP_LOGI(TAG, "[CALIBRATION][%s] --------------------------------------------------------------", cs);
1021
+
714
1022
  for (uint8_t phase = 0; phase < 3; phase++) {
715
- this->write_offsets_to_registers_(phase, 0, 0);
1023
+ int16_t voltage_offset =
1024
+ this->has_config_voltage_offset_[phase] ? this->config_offset_phase_[phase].voltage_offset_ : 0;
1025
+ int16_t current_offset =
1026
+ this->has_config_current_offset_[phase] ? this->config_offset_phase_[phase].current_offset_ : 0;
1027
+ this->write_offsets_to_registers_(phase, voltage_offset, current_offset);
1028
+ ESP_LOGI(TAG, "[CALIBRATION][%s] | %c | %6d | %6d |", cs, 'A' + phase, voltage_offset,
1029
+ current_offset);
716
1030
  }
1031
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ==============================================================\n", cs);
1032
+
1033
+ OffsetCalibration zero_offsets[3]{{0, 0}, {0, 0}, {0, 0}};
1034
+ this->offset_pref_.save(&zero_offsets); // Clear stored values in flash
1035
+ global_preferences->sync();
717
1036
 
718
- this->offset_pref_.save(&this->offset_phase_); // Save cleared values to flash memory
1037
+ this->restored_offset_calibration_ = false;
1038
+ for (bool &phase : this->offset_calibration_mismatch_)
1039
+ phase = false;
719
1040
 
720
- ESP_LOGI(TAG, "[CALIBRATION] Offsets cleared.");
1041
+ ESP_LOGI(TAG, "[CALIBRATION][%s] Offsets cleared.", cs);
721
1042
  }
722
1043
 
723
1044
  void ATM90E32Component::clear_power_offset_calibrations() {
1045
+ const char *cs = this->cs_summary_.c_str();
1046
+ if (!this->restored_power_offset_calibration_) {
1047
+ ESP_LOGI(TAG, "[CALIBRATION][%s] No stored power offsets to clear. Current values:", cs);
1048
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ---------------------------------------------------------------------", cs);
1049
+ ESP_LOGI(TAG, "[CALIBRATION][%s] | Phase | offset_active_power | offset_reactive_power |", cs);
1050
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ---------------------------------------------------------------------", cs);
1051
+ for (uint8_t phase = 0; phase < 3; phase++) {
1052
+ ESP_LOGI(TAG, "[CALIBRATION][%s] | %c | %6d | %6d |", cs, 'A' + phase,
1053
+ this->power_offset_phase_[phase].active_power_offset,
1054
+ this->power_offset_phase_[phase].reactive_power_offset);
1055
+ }
1056
+ ESP_LOGI(TAG, "[CALIBRATION][%s] =====================================================================\n", cs);
1057
+ return;
1058
+ }
1059
+
1060
+ ESP_LOGI(TAG, "[CALIBRATION][%s] Clearing stored power offsets and restoring config-defined values", cs);
1061
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ---------------------------------------------------------------------", cs);
1062
+ ESP_LOGI(TAG, "[CALIBRATION][%s] | Phase | offset_active_power | offset_reactive_power |", cs);
1063
+ ESP_LOGI(TAG, "[CALIBRATION][%s] ---------------------------------------------------------------------", cs);
1064
+
724
1065
  for (uint8_t phase = 0; phase < 3; phase++) {
725
- this->write_power_offsets_to_registers_(phase, 0, 0);
1066
+ int16_t active_offset =
1067
+ this->has_config_active_power_offset_[phase] ? this->config_power_offset_phase_[phase].active_power_offset : 0;
1068
+ int16_t reactive_offset = this->has_config_reactive_power_offset_[phase]
1069
+ ? this->config_power_offset_phase_[phase].reactive_power_offset
1070
+ : 0;
1071
+ this->write_power_offsets_to_registers_(phase, active_offset, reactive_offset);
1072
+ ESP_LOGI(TAG, "[CALIBRATION][%s] | %c | %6d | %6d |", cs, 'A' + phase, active_offset,
1073
+ reactive_offset);
726
1074
  }
1075
+ ESP_LOGI(TAG, "[CALIBRATION][%s] =====================================================================\n", cs);
727
1076
 
728
- this->power_offset_pref_.save(&this->power_offset_phase_);
1077
+ PowerOffsetCalibration zero_power_offsets[3]{{0, 0}, {0, 0}, {0, 0}};
1078
+ this->power_offset_pref_.save(&zero_power_offsets);
1079
+ global_preferences->sync();
729
1080
 
730
- ESP_LOGI(TAG, "[CALIBRATION] Power offsets cleared.");
1081
+ this->restored_power_offset_calibration_ = false;
1082
+ for (bool &phase : this->power_offset_calibration_mismatch_)
1083
+ phase = false;
1084
+
1085
+ ESP_LOGI(TAG, "[CALIBRATION][%s] Power offsets cleared.", cs);
731
1086
  }
732
1087
 
733
1088
  int16_t ATM90E32Component::calibrate_offset(uint8_t phase, bool voltage) {
@@ -748,20 +1103,21 @@ int16_t ATM90E32Component::calibrate_offset(uint8_t phase, bool voltage) {
748
1103
 
749
1104
  int16_t ATM90E32Component::calibrate_power_offset(uint8_t phase, bool reactive) {
750
1105
  const uint8_t num_reads = 5;
751
- uint64_t total_value = 0;
1106
+ int64_t total_value = 0;
752
1107
 
753
1108
  for (uint8_t i = 0; i < num_reads; ++i) {
754
- uint32_t reading = reactive ? this->read32_(ATM90E32_REGISTER_QMEAN + phase, ATM90E32_REGISTER_QMEANLSB + phase)
755
- : this->read32_(ATM90E32_REGISTER_PMEAN + phase, ATM90E32_REGISTER_PMEANLSB + phase);
1109
+ int32_t reading = reactive ? this->read32_(ATM90E32_REGISTER_QMEAN + phase, ATM90E32_REGISTER_QMEANLSB + phase)
1110
+ : this->read32_(ATM90E32_REGISTER_PMEAN + phase, ATM90E32_REGISTER_PMEANLSB + phase);
756
1111
  total_value += reading;
757
1112
  }
758
1113
 
759
- const uint32_t average_value = total_value / num_reads;
760
- const uint32_t power_offset = ~average_value + 1;
1114
+ int32_t average_value = total_value / num_reads;
1115
+ int32_t power_offset = -average_value;
761
1116
  return static_cast<int16_t>(power_offset); // Takes the lower 16 bits
762
1117
  }
763
1118
 
764
1119
  bool ATM90E32Component::verify_gain_writes_() {
1120
+ const char *cs = this->cs_summary_.c_str();
765
1121
  bool success = true;
766
1122
  for (uint8_t phase = 0; phase < 3; phase++) {
767
1123
  uint16_t read_voltage = this->read16_(voltage_gain_registers[phase]);
@@ -769,7 +1125,7 @@ bool ATM90E32Component::verify_gain_writes_() {
769
1125
 
770
1126
  if (read_voltage != this->gain_phase_[phase].voltage_gain ||
771
1127
  read_current != this->gain_phase_[phase].current_gain) {
772
- ESP_LOGE(TAG, "[CALIBRATION] Mismatch detected for Phase %s!", phase_labels[phase]);
1128
+ ESP_LOGE(TAG, "[CALIBRATION][%s] Mismatch detected for Phase %s!", cs, phase_labels[phase]);
773
1129
  success = false;
774
1130
  }
775
1131
  }
@@ -792,16 +1148,16 @@ void ATM90E32Component::check_phase_status() {
792
1148
  status += "Phase Loss; ";
793
1149
 
794
1150
  auto *sensor = this->phase_status_text_sensor_[phase];
795
- const char *phase_name = sensor ? sensor->get_name().c_str() : "Unknown Phase";
1151
+ if (sensor == nullptr)
1152
+ continue;
1153
+
796
1154
  if (!status.empty()) {
797
1155
  status.pop_back(); // remove space
798
1156
  status.pop_back(); // remove semicolon
799
- ESP_LOGW(TAG, "%s: %s", phase_name, status.c_str());
800
- if (sensor != nullptr)
801
- sensor->publish_state(status);
1157
+ ESP_LOGW(TAG, "%s: %s", sensor->get_name().c_str(), status.c_str());
1158
+ sensor->publish_state(status);
802
1159
  } else {
803
- if (sensor != nullptr)
804
- sensor->publish_state("Okay");
1160
+ sensor->publish_state("Okay");
805
1161
  }
806
1162
  }
807
1163
  }
@@ -818,9 +1174,12 @@ void ATM90E32Component::check_freq_status() {
818
1174
  } else {
819
1175
  freq_status = "Normal";
820
1176
  }
821
- ESP_LOGW(TAG, "Frequency status: %s", freq_status.c_str());
822
-
823
1177
  if (this->freq_status_text_sensor_ != nullptr) {
1178
+ if (freq_status == "Normal") {
1179
+ ESP_LOGD(TAG, "Frequency status: %s", freq_status.c_str());
1180
+ } else {
1181
+ ESP_LOGW(TAG, "Frequency status: %s", freq_status.c_str());
1182
+ }
824
1183
  this->freq_status_text_sensor_->publish_state(freq_status);
825
1184
  }
826
1185
  }