esphome 2025.8.4__py3-none-any.whl → 2025.9.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- esphome/__main__.py +177 -105
- esphome/components/absolute_humidity/absolute_humidity.cpp +3 -5
- esphome/components/adc/__init__.py +1 -26
- esphome/components/adc/adc_sensor_esp32.cpp +29 -6
- esphome/components/adc/sensor.py +20 -0
- esphome/components/ade7880/ade7880.cpp +1 -1
- esphome/components/ags10/ags10.cpp +3 -18
- esphome/components/ags10/ags10.h +2 -12
- esphome/components/aht10/aht10.cpp +3 -3
- esphome/components/airthings_ble/__init__.py +2 -2
- esphome/components/alarm_control_panel/__init__.py +2 -2
- esphome/components/am2315c/am2315c.cpp +1 -17
- esphome/components/am2315c/am2315c.h +2 -3
- esphome/components/api/__init__.py +2 -2
- esphome/components/api/api_connection.cpp +38 -34
- esphome/components/api/api_connection.h +20 -40
- esphome/components/api/api_frame_helper.cpp +25 -25
- esphome/components/api/api_frame_helper.h +3 -3
- esphome/components/api/api_frame_helper_noise.cpp +75 -40
- esphome/components/api/api_frame_helper_noise.h +3 -7
- esphome/components/api/api_frame_helper_plaintext.cpp +17 -4
- esphome/components/api/api_frame_helper_plaintext.h +1 -4
- esphome/components/api/api_pb2.cpp +12 -2
- esphome/components/api/api_pb2.h +144 -143
- esphome/components/api/api_pb2_dump.cpp +6 -1
- esphome/components/api/api_pb2_service.cpp +0 -14
- esphome/components/api/api_pb2_service.h +1 -3
- esphome/components/api/client.py +5 -3
- esphome/components/api/proto.cpp +33 -37
- esphome/components/async_tcp/__init__.py +2 -2
- esphome/components/atm90e26/sensor.py +2 -0
- esphome/components/atm90e32/sensor.py +4 -2
- esphome/components/audio_adc/__init__.py +2 -2
- esphome/components/audio_dac/__init__.py +2 -2
- esphome/components/axs15231/touchscreen/axs15231_touchscreen.cpp +1 -1
- esphome/components/bedjet/bedjet_hub.cpp +1 -1
- esphome/components/binary_sensor/__init__.py +2 -2
- esphome/components/binary_sensor/binary_sensor.cpp +13 -0
- esphome/components/binary_sensor/binary_sensor.h +4 -7
- esphome/components/bl0940/__init__.py +6 -1
- esphome/components/bl0940/bl0940.cpp +178 -41
- esphome/components/bl0940/bl0940.h +121 -76
- esphome/components/bl0940/button/__init__.py +27 -0
- esphome/components/bl0940/button/calibration_reset_button.cpp +20 -0
- esphome/components/bl0940/button/calibration_reset_button.h +19 -0
- esphome/components/bl0940/number/__init__.py +94 -0
- esphome/components/bl0940/number/calibration_number.cpp +29 -0
- esphome/components/bl0940/number/calibration_number.h +26 -0
- esphome/components/bl0940/sensor.py +151 -2
- esphome/components/bl0942/bl0942.cpp +1 -1
- esphome/components/ble_client/output/__init__.py +4 -4
- esphome/components/bluetooth_proxy/__init__.py +1 -1
- esphome/components/bluetooth_proxy/bluetooth_connection.h +1 -1
- esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +15 -7
- esphome/components/bluetooth_proxy/bluetooth_proxy.h +6 -3
- esphome/components/button/__init__.py +2 -2
- esphome/components/button/button.cpp +13 -0
- esphome/components/button/button.h +4 -7
- esphome/components/camera/buffer.h +18 -0
- esphome/components/camera/buffer_impl.cpp +20 -0
- esphome/components/camera/buffer_impl.h +26 -0
- esphome/components/camera/camera.h +43 -0
- esphome/components/camera/encoder.h +69 -0
- esphome/components/camera_encoder/__init__.py +62 -0
- esphome/components/camera_encoder/encoder_buffer_impl.cpp +23 -0
- esphome/components/camera_encoder/encoder_buffer_impl.h +25 -0
- esphome/components/camera_encoder/esp32_camera_jpeg_encoder.cpp +82 -0
- esphome/components/camera_encoder/esp32_camera_jpeg_encoder.h +39 -0
- esphome/components/captive_portal/__init__.py +2 -2
- esphome/components/captive_portal/captive_index.h +77 -97
- esphome/components/captive_portal/captive_portal.cpp +35 -12
- esphome/components/captive_portal/captive_portal.h +3 -3
- esphome/components/ccs811/ccs811.cpp +3 -3
- esphome/components/climate/__init__.py +2 -2
- esphome/components/climate/climate.cpp +1 -1
- esphome/components/cover/__init__.py +5 -5
- esphome/components/cover/cover.cpp +1 -1
- esphome/components/cover/cover.h +2 -2
- esphome/components/dallas_temp/dallas_temp.cpp +2 -2
- esphome/components/datetime/__init__.py +2 -2
- esphome/components/datetime/date_entity.h +2 -2
- esphome/components/datetime/datetime_entity.h +2 -2
- esphome/components/datetime/time_entity.h +2 -2
- esphome/components/debug/debug_esp32.cpp +1 -1
- esphome/components/display/__init__.py +4 -4
- esphome/components/duty_time/duty_time_sensor.cpp +1 -1
- esphome/components/esp32/__init__.py +0 -5
- esphome/components/esp32/gpio.cpp +27 -23
- esphome/components/esp32/gpio.h +26 -11
- esphome/components/esp32/preferences.cpp +8 -4
- esphome/components/esp32_ble/__init__.py +7 -2
- esphome/components/esp32_ble/ble_uuid.cpp +30 -9
- esphome/components/esp32_ble_beacon/esp32_ble_beacon.cpp +4 -3
- esphome/components/esp32_ble_client/ble_client_base.cpp +7 -3
- esphome/components/esp32_ble_client/ble_client_base.h +8 -5
- esphome/components/esp32_ble_tracker/__init__.py +2 -2
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +11 -47
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +2 -14
- esphome/components/esp8266/__init__.py +2 -2
- esphome/components/esp8266/core.cpp +2 -2
- esphome/components/esp8266/gpio.py +4 -4
- esphome/components/esp8266/preferences.cpp +30 -28
- esphome/components/esphome/ota/__init__.py +2 -2
- esphome/components/esphome/ota/ota_esphome.cpp +21 -19
- esphome/components/esphome/ota/ota_esphome.h +6 -5
- esphome/components/ethernet/__init__.py +18 -2
- esphome/components/ethernet/ethernet_component.cpp +53 -3
- esphome/components/ethernet/ethernet_component.h +4 -0
- esphome/components/event/__init__.py +2 -2
- esphome/components/event/event.h +4 -4
- esphome/components/factory_reset/button/factory_reset_button.cpp +18 -1
- esphome/components/factory_reset/button/factory_reset_button.h +6 -1
- esphome/components/factory_reset/switch/factory_reset_switch.cpp +18 -1
- esphome/components/factory_reset/switch/factory_reset_switch.h +5 -1
- esphome/components/fan/__init__.py +2 -2
- esphome/components/fan/fan.cpp +2 -1
- esphome/components/gdk101/gdk101.cpp +4 -4
- esphome/components/globals/__init__.py +2 -2
- esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp +19 -18
- esphome/components/gpio_expander/cached_gpio.h +36 -16
- esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.cpp +5 -5
- esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +1 -1
- esphome/components/haier/haier_base.cpp +1 -1
- esphome/components/haier/hon_climate.cpp +1 -1
- esphome/components/hlw8012/hlw8012.cpp +5 -5
- esphome/components/honeywellabp2_i2c/honeywellabp2.cpp +4 -4
- esphome/components/host/preferences.h +3 -2
- esphome/components/hte501/hte501.cpp +3 -21
- esphome/components/hte501/hte501.h +2 -3
- esphome/components/http_request/ota/__init__.py +2 -2
- esphome/components/i2c/__init__.py +2 -2
- esphome/components/i2c/i2c.cpp +13 -9
- esphome/components/i2c/i2c_bus.h +36 -6
- esphome/components/i2s_audio/__init__.py +8 -2
- esphome/components/i2s_audio/media_player/__init__.py +1 -1
- esphome/components/i2s_audio/microphone/__init__.py +1 -1
- esphome/components/i2s_audio/speaker/__init__.py +1 -1
- esphome/components/ina2xx_base/__init__.py +4 -2
- esphome/components/inkplate/__init__.py +1 -0
- esphome/components/inkplate/const.py +105 -0
- esphome/components/inkplate/display.py +238 -0
- esphome/components/{inkplate6 → inkplate}/inkplate.cpp +156 -74
- esphome/components/{inkplate6 → inkplate}/inkplate.h +28 -68
- esphome/components/inkplate6/__init__.py +0 -1
- esphome/components/inkplate6/display.py +2 -211
- esphome/components/integration/integration_sensor.cpp +1 -1
- esphome/components/json/__init__.py +2 -2
- esphome/components/lc709203f/lc709203f.cpp +4 -17
- esphome/components/lc709203f/lc709203f.h +2 -3
- esphome/components/ld2420/text_sensor/{text_sensor.cpp → ld2420_text_sensor.cpp} +1 -1
- esphome/components/ld2450/ld2450.cpp +1 -1
- esphome/components/libretiny/preferences.cpp +13 -5
- esphome/components/light/__init__.py +2 -2
- esphome/components/light/addressable_light_effect.h +7 -0
- esphome/components/light/base_light_effects.h +8 -0
- esphome/components/light/light_call.cpp +22 -20
- esphome/components/light/light_effect.cpp +36 -0
- esphome/components/light/light_effect.h +14 -0
- esphome/components/light/light_json_schema.cpp +9 -1
- esphome/components/light/light_state.cpp +2 -2
- esphome/components/light/light_state.h +38 -0
- esphome/components/lock/__init__.py +2 -2
- esphome/components/lock/lock.h +2 -2
- esphome/components/logger/__init__.py +2 -2
- esphome/components/logger/logger.cpp +25 -4
- esphome/components/logger/logger.h +1 -1
- esphome/components/logger/logger_esp32.cpp +16 -8
- esphome/components/logger/logger_esp8266.cpp +11 -3
- esphome/components/logger/logger_libretiny.cpp +13 -3
- esphome/components/logger/logger_rp2040.cpp +14 -3
- esphome/components/logger/logger_zephyr.cpp +15 -4
- esphome/components/lvgl/defines.py +1 -0
- esphome/components/lvgl/hello_world.py +96 -33
- esphome/components/lvgl/number/lvgl_number.h +1 -1
- esphome/components/lvgl/select/lvgl_select.h +1 -1
- esphome/components/lvgl/widgets/__init__.py +0 -1
- esphome/components/lvgl/widgets/spinbox.py +20 -11
- esphome/components/m5stack_8angle/binary_sensor/m5stack_8angle_binary_sensor.cpp +1 -1
- esphome/components/m5stack_8angle/sensor/m5stack_8angle_sensor.cpp +1 -1
- esphome/components/mapping/__init__.py +13 -5
- esphome/components/mapping/mapping.h +69 -0
- esphome/components/max17043/max17043.cpp +2 -2
- esphome/components/mcp23016/__init__.py +1 -0
- esphome/components/mcp23016/mcp23016.cpp +20 -5
- esphome/components/mcp23016/mcp23016.h +10 -4
- esphome/components/mcp23x08_base/mcp23x08_base.cpp +1 -1
- esphome/components/mcp23x17_base/mcp23x17_base.cpp +2 -2
- esphome/components/md5/md5.cpp +3 -2
- esphome/components/mdns/__init__.py +2 -2
- esphome/components/mdns/mdns_component.cpp +145 -54
- esphome/components/media_player/__init__.py +2 -2
- esphome/components/micro_wake_word/__init__.py +2 -2
- esphome/components/microphone/__init__.py +2 -2
- esphome/components/mipi/__init__.py +77 -33
- esphome/components/mipi_rgb/__init__.py +2 -0
- esphome/components/mipi_rgb/display.py +321 -0
- esphome/components/mipi_rgb/mipi_rgb.cpp +388 -0
- esphome/components/mipi_rgb/mipi_rgb.h +127 -0
- esphome/components/mipi_rgb/models/guition.py +24 -0
- esphome/components/mipi_rgb/models/lilygo.py +228 -0
- esphome/components/mipi_rgb/models/rpi.py +9 -0
- esphome/components/mipi_rgb/models/st7701s.py +214 -0
- esphome/components/mipi_rgb/models/waveshare.py +64 -0
- esphome/components/mipi_spi/models/jc.py +229 -0
- esphome/components/mlx90614/mlx90614.cpp +1 -16
- esphome/components/mlx90614/mlx90614.h +0 -1
- esphome/components/mqtt/__init__.py +2 -2
- esphome/components/mqtt/mqtt_client.cpp +1 -1
- esphome/components/mqtt/mqtt_sensor.cpp +7 -2
- esphome/components/ms5611/ms5611.cpp +7 -6
- esphome/components/network/__init__.py +2 -2
- esphome/components/nextion/nextion_upload.cpp +4 -1
- esphome/components/nrf52/__init__.py +49 -6
- esphome/components/nrf52/const.py +1 -0
- esphome/components/nrf52/dfu.cpp +51 -0
- esphome/components/nrf52/dfu.h +24 -0
- esphome/components/ntc/ntc.cpp +1 -1
- esphome/components/number/__init__.py +2 -2
- esphome/components/number/automation.cpp +1 -1
- esphome/components/number/number.cpp +21 -0
- esphome/components/number/number.h +4 -13
- esphome/components/opentherm/hub.h +6 -6
- esphome/components/opentherm/number/{number.cpp → opentherm_number.cpp} +2 -2
- esphome/components/opentherm/output/{output.cpp → opentherm_output.cpp} +1 -1
- esphome/components/opentherm/switch/{switch.cpp → opentherm_switch.cpp} +1 -1
- esphome/components/openthread/openthread.cpp +41 -7
- esphome/components/openthread/openthread.h +11 -0
- esphome/components/ota/__init__.py +2 -2
- esphome/components/pca6416a/__init__.py +1 -0
- esphome/components/pca6416a/pca6416a.cpp +20 -5
- esphome/components/pca6416a/pca6416a.h +12 -5
- esphome/components/pca9554/__init__.py +2 -1
- esphome/components/pca9554/pca9554.cpp +12 -18
- esphome/components/pca9554/pca9554.h +10 -9
- esphome/components/pcf8574/__init__.py +1 -0
- esphome/components/pcf8574/pcf8574.cpp +14 -5
- esphome/components/pcf8574/pcf8574.h +13 -6
- esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +7 -7
- esphome/components/pipsolar/__init__.py +3 -3
- esphome/components/pipsolar/output/__init__.py +4 -4
- esphome/components/pulse_width/pulse_width.cpp +2 -2
- esphome/components/qmp6988/qmp6988.cpp +81 -126
- esphome/components/qmp6988/qmp6988.h +31 -37
- esphome/components/radon_eye_ble/__init__.py +2 -2
- esphome/components/remote_base/__init__.py +6 -8
- esphome/components/rotary_encoder/rotary_encoder.cpp +1 -1
- esphome/components/rp2040/__init__.py +2 -2
- esphome/components/runtime_stats/runtime_stats.cpp +10 -23
- esphome/components/runtime_stats/runtime_stats.h +4 -10
- esphome/components/safe_mode/__init__.py +2 -2
- esphome/components/safe_mode/safe_mode.cpp +33 -31
- esphome/components/script/script.cpp +6 -0
- esphome/components/script/script.h +19 -5
- esphome/components/sdm_meter/sensor.py +3 -1
- esphome/components/select/__init__.py +2 -2
- esphome/components/select/select.cpp +3 -3
- esphome/components/select/select.h +2 -2
- esphome/components/select/select_call.cpp +1 -1
- esphome/components/sen5x/sen5x.cpp +57 -55
- esphome/components/sen5x/sen5x.h +21 -15
- esphome/components/sen5x/sensor.py +67 -44
- esphome/components/sensirion_common/i2c_sensirion.cpp +18 -47
- esphome/components/sensirion_common/i2c_sensirion.h +39 -55
- esphome/components/sensor/__init__.py +2 -2
- esphome/components/sensor/automation.h +1 -1
- esphome/components/sensor/sensor.cpp +34 -6
- esphome/components/sensor/sensor.h +4 -21
- esphome/components/sgp30/sgp30.cpp +34 -35
- esphome/components/sgp30/sgp30.h +11 -10
- esphome/components/sgp4x/sgp4x.cpp +2 -2
- esphome/components/shelly_dimmer/light.py +7 -7
- esphome/components/sht4x/sht4x.cpp +1 -1
- esphome/components/sntp/sntp_component.cpp +36 -9
- esphome/components/sntp/sntp_component.h +7 -0
- esphome/components/sound_level/sound_level.cpp +1 -1
- esphome/components/speaker/__init__.py +2 -2
- esphome/components/speaker/media_player/__init__.py +2 -2
- esphome/components/speaker/media_player/speaker_media_player.cpp +1 -1
- esphome/components/spi/__init__.py +2 -2
- esphome/components/sprinkler/sprinkler.cpp +1 -1
- esphome/components/sps30/sps30.cpp +18 -23
- esphome/components/sps30/sps30.h +3 -3
- esphome/components/status_led/__init__.py +2 -2
- esphome/components/stepper/__init__.py +2 -2
- esphome/components/switch/__init__.py +2 -2
- esphome/components/switch/switch.cpp +5 -5
- esphome/components/sx1509/__init__.py +1 -1
- esphome/components/sx1509/sx1509.cpp +12 -7
- esphome/components/sx1509/sx1509.h +11 -4
- esphome/components/tca9555/tca9555.cpp +5 -5
- esphome/components/tee501/tee501.cpp +2 -21
- esphome/components/tee501/tee501.h +2 -4
- esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +1 -1
- esphome/components/template/datetime/template_date.cpp +1 -1
- esphome/components/template/datetime/template_datetime.cpp +2 -2
- esphome/components/template/datetime/template_time.cpp +1 -1
- esphome/components/template/number/template_number.cpp +1 -1
- esphome/components/template/select/template_select.cpp +1 -1
- esphome/components/template/text/template_text.cpp +1 -1
- esphome/components/text/__init__.py +2 -2
- esphome/components/text/text.h +2 -2
- esphome/components/text_sensor/__init__.py +2 -2
- esphome/components/text_sensor/text_sensor.h +4 -4
- esphome/components/thermostat/climate.py +11 -7
- esphome/components/thermostat/thermostat_climate.cpp +237 -206
- esphome/components/thermostat/thermostat_climate.h +52 -41
- esphome/components/time/__init__.py +2 -2
- esphome/components/tmp1075/tmp1075.cpp +1 -1
- esphome/components/total_daily_energy/total_daily_energy.cpp +1 -1
- esphome/components/touchscreen/__init__.py +2 -2
- esphome/components/tuya/number/tuya_number.cpp +1 -1
- esphome/components/udp/udp_component.cpp +3 -3
- esphome/components/ufire_ec/ufire_ec.cpp +4 -4
- esphome/components/ufire_ise/ufire_ise.cpp +4 -4
- esphome/components/update/__init__.py +2 -2
- esphome/components/usb_uart/usb_uart.cpp +1 -1
- esphome/components/valve/__init__.py +5 -5
- esphome/components/valve/valve.cpp +1 -1
- esphome/components/valve/valve.h +2 -2
- esphome/components/wake_on_lan/wake_on_lan.cpp +2 -2
- esphome/components/waveshare_epaper/waveshare_213v3.cpp +1 -1
- esphome/components/web_server/__init__.py +2 -2
- esphome/components/web_server/ota/__init__.py +2 -2
- esphome/components/web_server/ota/ota_web_server.cpp +11 -0
- esphome/components/web_server/server_index_v2.h +149 -149
- esphome/components/web_server/web_server.cpp +58 -12
- esphome/components/web_server_base/__init__.py +2 -2
- esphome/components/wifi/__init__.py +5 -5
- esphome/components/wifi/wifi_component.cpp +4 -4
- esphome/components/wifi/wifi_component_esp_idf.cpp +2 -0
- esphome/components/wifi_info/wifi_info_text_sensor.h +3 -2
- esphome/config_validation.py +2 -2
- esphome/const.py +3 -1
- esphome/core/__init__.py +1 -0
- esphome/core/application.cpp +89 -51
- esphome/core/application.h +1 -0
- esphome/core/component.cpp +41 -19
- esphome/core/component.h +17 -13
- esphome/core/config.py +7 -7
- esphome/core/defines.h +5 -0
- esphome/core/entity_base.cpp +22 -8
- esphome/core/entity_base.h +43 -0
- esphome/core/helpers.cpp +34 -20
- esphome/core/helpers.h +33 -3
- esphome/core/ring_buffer.cpp +6 -2
- esphome/core/ring_buffer.h +2 -1
- esphome/core/scheduler.cpp +178 -97
- esphome/core/scheduler.h +67 -36
- esphome/core/time.cpp +6 -20
- esphome/coroutine.py +80 -3
- esphome/cpp_generator.py +13 -0
- esphome/cpp_helpers.py +2 -2
- esphome/dashboard/web_server.py +69 -15
- esphome/espota2.py +13 -6
- esphome/helpers.py +68 -83
- esphome/resolver.py +67 -0
- esphome/util.py +9 -6
- esphome/wizard.py +81 -34
- esphome/writer.py +13 -0
- {esphome-2025.8.4.dist-info → esphome-2025.9.0.dist-info}/METADATA +9 -9
- {esphome-2025.8.4.dist-info → esphome-2025.9.0.dist-info}/RECORD +369 -338
- /esphome/components/ld2420/text_sensor/{text_sensor.h → ld2420_text_sensor.h} +0 -0
- /esphome/components/opentherm/number/{number.h → opentherm_number.h} +0 -0
- /esphome/components/opentherm/output/{output.h → opentherm_output.h} +0 -0
- /esphome/components/opentherm/switch/{switch.h → opentherm_switch.h} +0 -0
- {esphome-2025.8.4.dist-info → esphome-2025.9.0.dist-info}/WHEEL +0 -0
- {esphome-2025.8.4.dist-info → esphome-2025.9.0.dist-info}/entry_points.txt +0 -0
- {esphome-2025.8.4.dist-info → esphome-2025.9.0.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.8.4.dist-info → esphome-2025.9.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,94 @@
|
|
1
|
+
import esphome.codegen as cg
|
2
|
+
from esphome.components import number
|
3
|
+
import esphome.config_validation as cv
|
4
|
+
from esphome.const import (
|
5
|
+
CONF_MAX_VALUE,
|
6
|
+
CONF_MIN_VALUE,
|
7
|
+
CONF_MODE,
|
8
|
+
CONF_RESTORE_VALUE,
|
9
|
+
CONF_STEP,
|
10
|
+
ENTITY_CATEGORY_CONFIG,
|
11
|
+
UNIT_PERCENT,
|
12
|
+
)
|
13
|
+
|
14
|
+
from .. import CONF_BL0940_ID, bl0940_ns
|
15
|
+
from ..sensor import BL0940
|
16
|
+
|
17
|
+
# Define calibration types
|
18
|
+
CONF_CURRENT_CALIBRATION = "current_calibration"
|
19
|
+
CONF_VOLTAGE_CALIBRATION = "voltage_calibration"
|
20
|
+
CONF_POWER_CALIBRATION = "power_calibration"
|
21
|
+
CONF_ENERGY_CALIBRATION = "energy_calibration"
|
22
|
+
|
23
|
+
BL0940Number = bl0940_ns.class_("BL0940Number")
|
24
|
+
|
25
|
+
CalibrationNumber = bl0940_ns.class_(
|
26
|
+
"CalibrationNumber", number.Number, cg.PollingComponent
|
27
|
+
)
|
28
|
+
|
29
|
+
|
30
|
+
def validate_min_max(config):
|
31
|
+
if config[CONF_MAX_VALUE] <= config[CONF_MIN_VALUE]:
|
32
|
+
raise cv.Invalid("max_value must be greater than min_value")
|
33
|
+
return config
|
34
|
+
|
35
|
+
|
36
|
+
CALIBRATION_SCHEMA = cv.All(
|
37
|
+
number.number_schema(
|
38
|
+
CalibrationNumber,
|
39
|
+
entity_category=ENTITY_CATEGORY_CONFIG,
|
40
|
+
unit_of_measurement=UNIT_PERCENT,
|
41
|
+
)
|
42
|
+
.extend(
|
43
|
+
{
|
44
|
+
cv.Optional(CONF_MODE, default="BOX"): cv.enum(number.NUMBER_MODES),
|
45
|
+
cv.Optional(CONF_MAX_VALUE, default=10): cv.All(
|
46
|
+
cv.float_, cv.Range(max=50)
|
47
|
+
),
|
48
|
+
cv.Optional(CONF_MIN_VALUE, default=-10): cv.All(
|
49
|
+
cv.float_, cv.Range(min=-50)
|
50
|
+
),
|
51
|
+
cv.Optional(CONF_STEP, default=0.1): cv.positive_float,
|
52
|
+
cv.Optional(CONF_RESTORE_VALUE): cv.boolean,
|
53
|
+
}
|
54
|
+
)
|
55
|
+
.extend(cv.COMPONENT_SCHEMA),
|
56
|
+
validate_min_max,
|
57
|
+
)
|
58
|
+
|
59
|
+
# Configuration schema for BL0940 numbers
|
60
|
+
CONFIG_SCHEMA = cv.Schema(
|
61
|
+
{
|
62
|
+
cv.GenerateID(): cv.declare_id(BL0940Number),
|
63
|
+
cv.GenerateID(CONF_BL0940_ID): cv.use_id(BL0940),
|
64
|
+
cv.Optional(CONF_CURRENT_CALIBRATION): CALIBRATION_SCHEMA,
|
65
|
+
cv.Optional(CONF_VOLTAGE_CALIBRATION): CALIBRATION_SCHEMA,
|
66
|
+
cv.Optional(CONF_POWER_CALIBRATION): CALIBRATION_SCHEMA,
|
67
|
+
cv.Optional(CONF_ENERGY_CALIBRATION): CALIBRATION_SCHEMA,
|
68
|
+
}
|
69
|
+
)
|
70
|
+
|
71
|
+
|
72
|
+
async def to_code(config):
|
73
|
+
# Get the BL0940 component instance
|
74
|
+
bl0940 = await cg.get_variable(config[CONF_BL0940_ID])
|
75
|
+
|
76
|
+
# Process all calibration types
|
77
|
+
for cal_type, setter_method in [
|
78
|
+
(CONF_CURRENT_CALIBRATION, "set_current_calibration_number"),
|
79
|
+
(CONF_VOLTAGE_CALIBRATION, "set_voltage_calibration_number"),
|
80
|
+
(CONF_POWER_CALIBRATION, "set_power_calibration_number"),
|
81
|
+
(CONF_ENERGY_CALIBRATION, "set_energy_calibration_number"),
|
82
|
+
]:
|
83
|
+
if conf := config.get(cal_type):
|
84
|
+
var = await number.new_number(
|
85
|
+
conf,
|
86
|
+
min_value=conf.get(CONF_MIN_VALUE),
|
87
|
+
max_value=conf.get(CONF_MAX_VALUE),
|
88
|
+
step=conf.get(CONF_STEP),
|
89
|
+
)
|
90
|
+
await cg.register_component(var, conf)
|
91
|
+
|
92
|
+
if restore_value := config.get(CONF_RESTORE_VALUE):
|
93
|
+
cg.add(var.set_restore_value(restore_value))
|
94
|
+
cg.add(getattr(bl0940, setter_method)(var))
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#include "calibration_number.h"
|
2
|
+
#include "esphome/core/log.h"
|
3
|
+
|
4
|
+
namespace esphome {
|
5
|
+
namespace bl0940 {
|
6
|
+
|
7
|
+
static const char *const TAG = "bl0940.number";
|
8
|
+
|
9
|
+
void CalibrationNumber::setup() {
|
10
|
+
float value = 0.0f;
|
11
|
+
if (this->restore_value_) {
|
12
|
+
this->pref_ = global_preferences->make_preference<float>(this->get_object_id_hash());
|
13
|
+
if (!this->pref_.load(&value)) {
|
14
|
+
value = 0.0f;
|
15
|
+
}
|
16
|
+
}
|
17
|
+
this->publish_state(value);
|
18
|
+
}
|
19
|
+
|
20
|
+
void CalibrationNumber::control(float value) {
|
21
|
+
this->publish_state(value);
|
22
|
+
if (this->restore_value_)
|
23
|
+
this->pref_.save(&value);
|
24
|
+
}
|
25
|
+
|
26
|
+
void CalibrationNumber::dump_config() { LOG_NUMBER("", "Calibration Number", this); }
|
27
|
+
|
28
|
+
} // namespace bl0940
|
29
|
+
} // namespace esphome
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "esphome/components/number/number.h"
|
4
|
+
#include "esphome/core/component.h"
|
5
|
+
#include "esphome/core/preferences.h"
|
6
|
+
|
7
|
+
namespace esphome {
|
8
|
+
namespace bl0940 {
|
9
|
+
|
10
|
+
class CalibrationNumber : public number::Number, public Component {
|
11
|
+
public:
|
12
|
+
void setup() override;
|
13
|
+
void dump_config() override;
|
14
|
+
float get_setup_priority() const override { return setup_priority::HARDWARE; }
|
15
|
+
|
16
|
+
void set_restore_value(bool restore_value) { this->restore_value_ = restore_value; }
|
17
|
+
|
18
|
+
protected:
|
19
|
+
void control(float value) override;
|
20
|
+
bool restore_value_{true};
|
21
|
+
|
22
|
+
ESPPreferenceObject pref_;
|
23
|
+
};
|
24
|
+
|
25
|
+
} // namespace bl0940
|
26
|
+
} // namespace esphome
|
@@ -8,6 +8,7 @@ from esphome.const import (
|
|
8
8
|
CONF_ID,
|
9
9
|
CONF_INTERNAL_TEMPERATURE,
|
10
10
|
CONF_POWER,
|
11
|
+
CONF_REFERENCE_VOLTAGE,
|
11
12
|
CONF_VOLTAGE,
|
12
13
|
DEVICE_CLASS_CURRENT,
|
13
14
|
DEVICE_CLASS_ENERGY,
|
@@ -23,12 +24,133 @@ from esphome.const import (
|
|
23
24
|
UNIT_WATT,
|
24
25
|
)
|
25
26
|
|
26
|
-
|
27
|
+
from . import bl0940_ns
|
27
28
|
|
29
|
+
DEPENDENCIES = ["uart"]
|
28
30
|
|
29
|
-
bl0940_ns = cg.esphome_ns.namespace("bl0940")
|
30
31
|
BL0940 = bl0940_ns.class_("BL0940", cg.PollingComponent, uart.UARTDevice)
|
31
32
|
|
33
|
+
CONF_LEGACY_MODE = "legacy_mode"
|
34
|
+
|
35
|
+
CONF_READ_COMMAND = "read_command"
|
36
|
+
CONF_WRITE_COMMAND = "write_command"
|
37
|
+
|
38
|
+
CONF_RESISTOR_SHUNT = "resistor_shunt"
|
39
|
+
CONF_RESISTOR_ONE = "resistor_one"
|
40
|
+
CONF_RESISTOR_TWO = "resistor_two"
|
41
|
+
|
42
|
+
CONF_CURRENT_REFERENCE = "current_reference"
|
43
|
+
CONF_ENERGY_REFERENCE = "energy_reference"
|
44
|
+
CONF_POWER_REFERENCE = "power_reference"
|
45
|
+
CONF_VOLTAGE_REFERENCE = "voltage_reference"
|
46
|
+
|
47
|
+
DEFAULT_BL0940_READ_COMMAND = 0x58
|
48
|
+
DEFAULT_BL0940_WRITE_COMMAND = 0xA1
|
49
|
+
|
50
|
+
# Values according to BL0940 application note:
|
51
|
+
# https://www.belling.com.cn/media/file_object/bel_product/BL0940/guide/BL0940_APPNote_TSSOP14_V1.04_EN.pdf
|
52
|
+
DEFAULT_BL0940_VREF = 1.218 # Vref = 1.218
|
53
|
+
DEFAULT_BL0940_RL = 1 # RL = 1 mΩ
|
54
|
+
DEFAULT_BL0940_R1 = 0.51 # R1 = 0.51 kΩ
|
55
|
+
DEFAULT_BL0940_R2 = 1950 # R2 = 5 x 390 kΩ -> 1950 kΩ
|
56
|
+
|
57
|
+
# ----------------------------------------------------
|
58
|
+
# values from initial implementation
|
59
|
+
DEFAULT_BL0940_LEGACY_READ_COMMAND = 0x50
|
60
|
+
DEFAULT_BL0940_LEGACY_WRITE_COMMAND = 0xA0
|
61
|
+
|
62
|
+
DEFAULT_BL0940_LEGACY_UREF = 33000
|
63
|
+
DEFAULT_BL0940_LEGACY_IREF = 275000
|
64
|
+
DEFAULT_BL0940_LEGACY_PREF = 1430
|
65
|
+
# Measured to 297J per click according to power consumption of 5 minutes
|
66
|
+
# Converted to kWh (3.6MJ per kwH). Used to be 256 * 1638.4
|
67
|
+
DEFAULT_BL0940_LEGACY_EREF = 3.6e6 / 297
|
68
|
+
# ----------------------------------------------------
|
69
|
+
|
70
|
+
|
71
|
+
# methods to calculate voltage and current reference values
|
72
|
+
def calculate_voltage_reference(vref, r_one, r_two):
|
73
|
+
# formula: 79931 / Vref * (R1 * 1000) / (R1 + R2)
|
74
|
+
return 79931 / vref * (r_one * 1000) / (r_one + r_two)
|
75
|
+
|
76
|
+
|
77
|
+
def calculate_current_reference(vref, r_shunt):
|
78
|
+
# formula: 324004 * RL / Vref
|
79
|
+
return 324004 * r_shunt / vref
|
80
|
+
|
81
|
+
|
82
|
+
def calculate_power_reference(voltage_reference, current_reference):
|
83
|
+
# calculate power reference based on voltage and current reference
|
84
|
+
return voltage_reference * current_reference * 4046 / 324004 / 79931
|
85
|
+
|
86
|
+
|
87
|
+
def calculate_energy_reference(power_reference):
|
88
|
+
# formula: power_reference * 3600000 / (1638.4 * 256)
|
89
|
+
return power_reference * 3600000 / (1638.4 * 256)
|
90
|
+
|
91
|
+
|
92
|
+
def validate_legacy_mode(config):
|
93
|
+
# Only allow schematic calibration options if legacy_mode is False
|
94
|
+
if config.get(CONF_LEGACY_MODE, True):
|
95
|
+
forbidden = [
|
96
|
+
CONF_REFERENCE_VOLTAGE,
|
97
|
+
CONF_RESISTOR_SHUNT,
|
98
|
+
CONF_RESISTOR_ONE,
|
99
|
+
CONF_RESISTOR_TWO,
|
100
|
+
]
|
101
|
+
for key in forbidden:
|
102
|
+
if key in config:
|
103
|
+
raise cv.Invalid(
|
104
|
+
f"Option '{key}' is only allowed when legacy_mode: false"
|
105
|
+
)
|
106
|
+
return config
|
107
|
+
|
108
|
+
|
109
|
+
def set_command_defaults(config):
|
110
|
+
# Set defaults for read_command and write_command based on legacy_mode
|
111
|
+
legacy = config.get(CONF_LEGACY_MODE, True)
|
112
|
+
if legacy:
|
113
|
+
config.setdefault(CONF_READ_COMMAND, DEFAULT_BL0940_LEGACY_READ_COMMAND)
|
114
|
+
config.setdefault(CONF_WRITE_COMMAND, DEFAULT_BL0940_LEGACY_WRITE_COMMAND)
|
115
|
+
else:
|
116
|
+
config.setdefault(CONF_READ_COMMAND, DEFAULT_BL0940_READ_COMMAND)
|
117
|
+
config.setdefault(CONF_WRITE_COMMAND, DEFAULT_BL0940_WRITE_COMMAND)
|
118
|
+
return config
|
119
|
+
|
120
|
+
|
121
|
+
def set_reference_values(config):
|
122
|
+
# Set default reference values based on legacy_mode
|
123
|
+
if config.get(CONF_LEGACY_MODE, True):
|
124
|
+
config.setdefault(CONF_VOLTAGE_REFERENCE, DEFAULT_BL0940_LEGACY_UREF)
|
125
|
+
config.setdefault(CONF_CURRENT_REFERENCE, DEFAULT_BL0940_LEGACY_IREF)
|
126
|
+
config.setdefault(CONF_POWER_REFERENCE, DEFAULT_BL0940_LEGACY_PREF)
|
127
|
+
config.setdefault(CONF_ENERGY_REFERENCE, DEFAULT_BL0940_LEGACY_PREF)
|
128
|
+
else:
|
129
|
+
vref = config.get(CONF_VOLTAGE_REFERENCE, DEFAULT_BL0940_VREF)
|
130
|
+
r_one = config.get(CONF_RESISTOR_ONE, DEFAULT_BL0940_R1)
|
131
|
+
r_two = config.get(CONF_RESISTOR_TWO, DEFAULT_BL0940_R2)
|
132
|
+
r_shunt = config.get(CONF_RESISTOR_SHUNT, DEFAULT_BL0940_RL)
|
133
|
+
|
134
|
+
config.setdefault(
|
135
|
+
CONF_VOLTAGE_REFERENCE, calculate_voltage_reference(vref, r_one, r_two)
|
136
|
+
)
|
137
|
+
config.setdefault(
|
138
|
+
CONF_CURRENT_REFERENCE, calculate_current_reference(vref, r_shunt)
|
139
|
+
)
|
140
|
+
config.setdefault(
|
141
|
+
CONF_POWER_REFERENCE,
|
142
|
+
calculate_power_reference(
|
143
|
+
config.get(CONF_VOLTAGE_REFERENCE), config.get(CONF_CURRENT_REFERENCE)
|
144
|
+
),
|
145
|
+
)
|
146
|
+
config.setdefault(
|
147
|
+
CONF_ENERGY_REFERENCE,
|
148
|
+
calculate_energy_reference(config.get(CONF_POWER_REFERENCE)),
|
149
|
+
)
|
150
|
+
|
151
|
+
return config
|
152
|
+
|
153
|
+
|
32
154
|
CONFIG_SCHEMA = (
|
33
155
|
cv.Schema(
|
34
156
|
{
|
@@ -69,10 +191,24 @@ CONFIG_SCHEMA = (
|
|
69
191
|
device_class=DEVICE_CLASS_TEMPERATURE,
|
70
192
|
state_class=STATE_CLASS_MEASUREMENT,
|
71
193
|
),
|
194
|
+
cv.Optional(CONF_LEGACY_MODE, default=True): cv.boolean,
|
195
|
+
cv.Optional(CONF_READ_COMMAND): cv.hex_uint8_t,
|
196
|
+
cv.Optional(CONF_WRITE_COMMAND): cv.hex_uint8_t,
|
197
|
+
cv.Optional(CONF_REFERENCE_VOLTAGE): cv.float_,
|
198
|
+
cv.Optional(CONF_RESISTOR_SHUNT): cv.float_,
|
199
|
+
cv.Optional(CONF_RESISTOR_ONE): cv.float_,
|
200
|
+
cv.Optional(CONF_RESISTOR_TWO): cv.float_,
|
201
|
+
cv.Optional(CONF_CURRENT_REFERENCE): cv.float_,
|
202
|
+
cv.Optional(CONF_ENERGY_REFERENCE): cv.float_,
|
203
|
+
cv.Optional(CONF_POWER_REFERENCE): cv.float_,
|
204
|
+
cv.Optional(CONF_VOLTAGE_REFERENCE): cv.float_,
|
72
205
|
}
|
73
206
|
)
|
74
207
|
.extend(cv.polling_component_schema("60s"))
|
75
208
|
.extend(uart.UART_DEVICE_SCHEMA)
|
209
|
+
.add_extra(validate_legacy_mode)
|
210
|
+
.add_extra(set_command_defaults)
|
211
|
+
.add_extra(set_reference_values)
|
76
212
|
)
|
77
213
|
|
78
214
|
|
@@ -99,3 +235,16 @@ async def to_code(config):
|
|
99
235
|
if external_temperature_config := config.get(CONF_EXTERNAL_TEMPERATURE):
|
100
236
|
sens = await sensor.new_sensor(external_temperature_config)
|
101
237
|
cg.add(var.set_external_temperature_sensor(sens))
|
238
|
+
|
239
|
+
# enable legacy mode
|
240
|
+
cg.add(var.set_legacy_mode(config.get(CONF_LEGACY_MODE)))
|
241
|
+
|
242
|
+
# Set bl0940 commands after validator has determined which defaults to use if not set
|
243
|
+
cg.add(var.set_read_command(config.get(CONF_READ_COMMAND)))
|
244
|
+
cg.add(var.set_write_command(config.get(CONF_WRITE_COMMAND)))
|
245
|
+
|
246
|
+
# Set reference values after validator has set the values either from defaults or calculated
|
247
|
+
cg.add(var.set_current_reference(config.get(CONF_CURRENT_REFERENCE)))
|
248
|
+
cg.add(var.set_voltage_reference(config.get(CONF_VOLTAGE_REFERENCE)))
|
249
|
+
cg.add(var.set_power_reference(config.get(CONF_POWER_REFERENCE)))
|
250
|
+
cg.add(var.set_energy_reference(config.get(CONF_ENERGY_REFERENCE)))
|
@@ -149,7 +149,7 @@ void BL0942::setup() {
|
|
149
149
|
this->write_reg_(BL0942_REG_USR_WRPROT, 0);
|
150
150
|
|
151
151
|
if (this->read_reg_(BL0942_REG_MODE) != mode)
|
152
|
-
this->status_set_warning("BL0942 setup failed!");
|
152
|
+
this->status_set_warning(LOG_STR("BL0942 setup failed!"));
|
153
153
|
|
154
154
|
this->flush();
|
155
155
|
}
|
@@ -27,7 +27,7 @@ CONFIG_SCHEMA = cv.All(
|
|
27
27
|
)
|
28
28
|
|
29
29
|
|
30
|
-
def to_code(config):
|
30
|
+
async def to_code(config):
|
31
31
|
var = cg.new_Pvariable(config[CONF_ID])
|
32
32
|
if len(config[CONF_SERVICE_UUID]) == len(esp32_ble_tracker.bt_uuid16_format):
|
33
33
|
cg.add(
|
@@ -63,6 +63,6 @@ def to_code(config):
|
|
63
63
|
)
|
64
64
|
cg.add(var.set_char_uuid128(uuid128))
|
65
65
|
cg.add(var.set_require_response(config[CONF_REQUIRE_RESPONSE]))
|
66
|
-
|
67
|
-
|
68
|
-
|
66
|
+
await output.register_output(var, config)
|
67
|
+
await ble_client.register_ble_node(var, config)
|
68
|
+
await cg.register_component(var, config)
|
@@ -80,7 +80,7 @@ CONFIG_SCHEMA = cv.All(
|
|
80
80
|
cv.Schema(
|
81
81
|
{
|
82
82
|
cv.GenerateID(): cv.declare_id(BluetoothProxy),
|
83
|
-
cv.Optional(CONF_ACTIVE, default=
|
83
|
+
cv.Optional(CONF_ACTIVE, default=True): cv.boolean,
|
84
84
|
cv.SplitDefault(CONF_CACHE_SERVICES, esp32_idf=True): cv.All(
|
85
85
|
cv.only_with_esp_idf, cv.boolean
|
86
86
|
),
|
@@ -8,7 +8,7 @@ namespace esphome::bluetooth_proxy {
|
|
8
8
|
|
9
9
|
class BluetoothProxy;
|
10
10
|
|
11
|
-
class BluetoothConnection : public esp32_ble_client::BLEClientBase {
|
11
|
+
class BluetoothConnection final : public esp32_ble_client::BLEClientBase {
|
12
12
|
public:
|
13
13
|
void dump_config() override;
|
14
14
|
void loop() override;
|
@@ -24,6 +24,9 @@ void BluetoothProxy::setup() {
|
|
24
24
|
this->connections_free_response_.limit = BLUETOOTH_PROXY_MAX_CONNECTIONS;
|
25
25
|
this->connections_free_response_.free = BLUETOOTH_PROXY_MAX_CONNECTIONS;
|
26
26
|
|
27
|
+
// Capture the configured scan mode from YAML before any API changes
|
28
|
+
this->configured_scan_active_ = this->parent_->get_scan_active();
|
29
|
+
|
27
30
|
this->parent_->add_scanner_state_callback([this](esp32_ble_tracker::ScannerState state) {
|
28
31
|
if (this->api_connection_ != nullptr) {
|
29
32
|
this->send_bluetooth_scanner_state_(state);
|
@@ -36,6 +39,9 @@ void BluetoothProxy::send_bluetooth_scanner_state_(esp32_ble_tracker::ScannerSta
|
|
36
39
|
resp.state = static_cast<api::enums::BluetoothScannerState>(state);
|
37
40
|
resp.mode = this->parent_->get_scan_active() ? api::enums::BluetoothScannerMode::BLUETOOTH_SCANNER_MODE_ACTIVE
|
38
41
|
: api::enums::BluetoothScannerMode::BLUETOOTH_SCANNER_MODE_PASSIVE;
|
42
|
+
resp.configured_mode = this->configured_scan_active_
|
43
|
+
? api::enums::BluetoothScannerMode::BLUETOOTH_SCANNER_MODE_ACTIVE
|
44
|
+
: api::enums::BluetoothScannerMode::BLUETOOTH_SCANNER_MODE_PASSIVE;
|
39
45
|
this->api_connection_->send_message(resp, api::BluetoothScannerStateResponse::MESSAGE_TYPE);
|
40
46
|
}
|
41
47
|
|
@@ -183,6 +189,12 @@ void BluetoothProxy::bluetooth_device_request(const api::BluetoothDeviceRequest
|
|
183
189
|
this->send_device_connection(msg.address, false);
|
184
190
|
return;
|
185
191
|
}
|
192
|
+
if (!msg.has_address_type) {
|
193
|
+
ESP_LOGE(TAG, "[%d] [%s] Missing address type in connect request", connection->get_connection_index(),
|
194
|
+
connection->address_str().c_str());
|
195
|
+
this->send_device_connection(msg.address, false);
|
196
|
+
return;
|
197
|
+
}
|
186
198
|
if (connection->state() == espbt::ClientState::CONNECTED ||
|
187
199
|
connection->state() == espbt::ClientState::ESTABLISHED) {
|
188
200
|
this->log_connection_request_ignored_(connection, connection->state());
|
@@ -209,13 +221,9 @@ void BluetoothProxy::bluetooth_device_request(const api::BluetoothDeviceRequest
|
|
209
221
|
connection->set_connection_type(espbt::ConnectionType::V3_WITHOUT_CACHE);
|
210
222
|
this->log_connection_info_(connection, "v3 without cache");
|
211
223
|
}
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
connection->set_state(espbt::ClientState::DISCOVERED);
|
216
|
-
} else {
|
217
|
-
connection->set_state(espbt::ClientState::SEARCHING);
|
218
|
-
}
|
224
|
+
uint64_to_bd_addr(msg.address, connection->remote_bda_);
|
225
|
+
connection->set_remote_addr_type(static_cast<esp_ble_addr_type_t>(msg.address_type));
|
226
|
+
connection->set_state(espbt::ClientState::DISCOVERED);
|
219
227
|
this->send_connections_free();
|
220
228
|
break;
|
221
229
|
}
|
@@ -50,7 +50,7 @@ enum BluetoothProxySubscriptionFlag : uint32_t {
|
|
50
50
|
SUBSCRIPTION_RAW_ADVERTISEMENTS = 1 << 0,
|
51
51
|
};
|
52
52
|
|
53
|
-
class BluetoothProxy : public esp32_ble_tracker::ESPBTDeviceListener, public Component {
|
53
|
+
class BluetoothProxy final : public esp32_ble_tracker::ESPBTDeviceListener, public Component {
|
54
54
|
friend class BluetoothConnection; // Allow connection to update connections_free_response_
|
55
55
|
public:
|
56
56
|
BluetoothProxy();
|
@@ -130,7 +130,9 @@ class BluetoothProxy : public esp32_ble_tracker::ESPBTDeviceListener, public Com
|
|
130
130
|
|
131
131
|
std::string get_bluetooth_mac_address_pretty() {
|
132
132
|
const uint8_t *mac = esp_bt_dev_get_address();
|
133
|
-
|
133
|
+
char buf[18];
|
134
|
+
format_mac_addr_upper(mac, buf);
|
135
|
+
return std::string(buf);
|
134
136
|
}
|
135
137
|
|
136
138
|
protected:
|
@@ -161,7 +163,8 @@ class BluetoothProxy : public esp32_ble_tracker::ESPBTDeviceListener, public Com
|
|
161
163
|
// Group 4: 1-byte types grouped together
|
162
164
|
bool active_;
|
163
165
|
uint8_t connection_count_{0};
|
164
|
-
//
|
166
|
+
bool configured_scan_active_{false}; // Configured scan mode from YAML
|
167
|
+
// 3 bytes used, 1 byte padding
|
165
168
|
};
|
166
169
|
|
167
170
|
extern BluetoothProxy *global_bluetooth_proxy; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
@@ -17,7 +17,7 @@ from esphome.const import (
|
|
17
17
|
DEVICE_CLASS_RESTART,
|
18
18
|
DEVICE_CLASS_UPDATE,
|
19
19
|
)
|
20
|
-
from esphome.core import CORE, coroutine_with_priority
|
20
|
+
from esphome.core import CORE, CoroPriority, coroutine_with_priority
|
21
21
|
from esphome.core.entity_helpers import entity_duplicate_validator, setup_entity
|
22
22
|
from esphome.cpp_generator import MockObjClass
|
23
23
|
|
@@ -134,6 +134,6 @@ async def button_press_to_code(config, action_id, template_arg, args):
|
|
134
134
|
return cg.new_Pvariable(action_id, template_arg, paren)
|
135
135
|
|
136
136
|
|
137
|
-
@coroutine_with_priority(
|
137
|
+
@coroutine_with_priority(CoroPriority.CORE)
|
138
138
|
async def to_code(config):
|
139
139
|
cg.add_global(button_ns.using)
|
@@ -6,6 +6,19 @@ namespace button {
|
|
6
6
|
|
7
7
|
static const char *const TAG = "button";
|
8
8
|
|
9
|
+
// Function implementation of LOG_BUTTON macro to reduce code size
|
10
|
+
void log_button(const char *tag, const char *prefix, const char *type, Button *obj) {
|
11
|
+
if (obj == nullptr) {
|
12
|
+
return;
|
13
|
+
}
|
14
|
+
|
15
|
+
ESP_LOGCONFIG(tag, "%s%s '%s'", prefix, type, obj->get_name().c_str());
|
16
|
+
|
17
|
+
if (!obj->get_icon_ref().empty()) {
|
18
|
+
ESP_LOGCONFIG(tag, "%s Icon: '%s'", prefix, obj->get_icon_ref().c_str());
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
9
22
|
void Button::press() {
|
10
23
|
ESP_LOGD(TAG, "'%s' Pressed.", this->get_name().c_str());
|
11
24
|
this->press_action();
|
@@ -7,13 +7,10 @@
|
|
7
7
|
namespace esphome {
|
8
8
|
namespace button {
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
ESP_LOGCONFIG(TAG, "%s Icon: '%s'", prefix, (obj)->get_icon().c_str()); \
|
15
|
-
} \
|
16
|
-
}
|
10
|
+
class Button;
|
11
|
+
void log_button(const char *tag, const char *prefix, const char *type, Button *obj);
|
12
|
+
|
13
|
+
#define LOG_BUTTON(prefix, type, obj) log_button(TAG, prefix, LOG_STR_LITERAL(type), obj)
|
17
14
|
|
18
15
|
#define SUB_BUTTON(name) \
|
19
16
|
protected: \
|
@@ -0,0 +1,18 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include <cinttypes>
|
4
|
+
#include <cstddef>
|
5
|
+
|
6
|
+
namespace esphome::camera {
|
7
|
+
|
8
|
+
/// Interface for a generic buffer that stores image data.
|
9
|
+
class Buffer {
|
10
|
+
public:
|
11
|
+
/// Returns a pointer to the buffer's data.
|
12
|
+
virtual uint8_t *get_data_buffer() = 0;
|
13
|
+
/// Returns the length of the buffer in bytes.
|
14
|
+
virtual size_t get_data_length() = 0;
|
15
|
+
virtual ~Buffer() = default;
|
16
|
+
};
|
17
|
+
|
18
|
+
} // namespace esphome::camera
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#include "buffer_impl.h"
|
2
|
+
|
3
|
+
namespace esphome::camera {
|
4
|
+
|
5
|
+
BufferImpl::BufferImpl(size_t size) {
|
6
|
+
this->data_ = this->allocator_.allocate(size);
|
7
|
+
this->size_ = size;
|
8
|
+
}
|
9
|
+
|
10
|
+
BufferImpl::BufferImpl(CameraImageSpec *spec) {
|
11
|
+
this->data_ = this->allocator_.allocate(spec->bytes_per_image());
|
12
|
+
this->size_ = spec->bytes_per_image();
|
13
|
+
}
|
14
|
+
|
15
|
+
BufferImpl::~BufferImpl() {
|
16
|
+
if (this->data_ != nullptr)
|
17
|
+
this->allocator_.deallocate(this->data_, this->size_);
|
18
|
+
}
|
19
|
+
|
20
|
+
} // namespace esphome::camera
|
@@ -0,0 +1,26 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "buffer.h"
|
4
|
+
#include "camera.h"
|
5
|
+
|
6
|
+
namespace esphome::camera {
|
7
|
+
|
8
|
+
/// Default implementation of Buffer Interface.
|
9
|
+
/// Uses a RAMAllocator for memory reservation.
|
10
|
+
class BufferImpl : public Buffer {
|
11
|
+
public:
|
12
|
+
explicit BufferImpl(size_t size);
|
13
|
+
explicit BufferImpl(CameraImageSpec *spec);
|
14
|
+
// -------- Buffer --------
|
15
|
+
uint8_t *get_data_buffer() override { return data_; }
|
16
|
+
size_t get_data_length() override { return size_; }
|
17
|
+
// ------------------------
|
18
|
+
~BufferImpl() override;
|
19
|
+
|
20
|
+
protected:
|
21
|
+
RAMAllocator<uint8_t> allocator_;
|
22
|
+
size_t size_{};
|
23
|
+
uint8_t *data_{};
|
24
|
+
};
|
25
|
+
|
26
|
+
} // namespace esphome::camera
|
@@ -15,6 +15,26 @@ namespace camera {
|
|
15
15
|
*/
|
16
16
|
enum CameraRequester : uint8_t { IDLE, API_REQUESTER, WEB_REQUESTER };
|
17
17
|
|
18
|
+
/// Enumeration of different pixel formats.
|
19
|
+
enum PixelFormat : uint8_t {
|
20
|
+
PIXEL_FORMAT_GRAYSCALE = 0, ///< 8-bit grayscale.
|
21
|
+
PIXEL_FORMAT_RGB565, ///< 16-bit RGB (5-6-5).
|
22
|
+
PIXEL_FORMAT_BGR888, ///< RGB pixel data in 8-bit format, stored as B, G, R (1 byte each).
|
23
|
+
};
|
24
|
+
|
25
|
+
/// Returns string name for a given PixelFormat.
|
26
|
+
inline const char *to_string(PixelFormat format) {
|
27
|
+
switch (format) {
|
28
|
+
case PIXEL_FORMAT_GRAYSCALE:
|
29
|
+
return "PIXEL_FORMAT_GRAYSCALE";
|
30
|
+
case PIXEL_FORMAT_RGB565:
|
31
|
+
return "PIXEL_FORMAT_RGB565";
|
32
|
+
case PIXEL_FORMAT_BGR888:
|
33
|
+
return "PIXEL_FORMAT_BGR888";
|
34
|
+
}
|
35
|
+
return "PIXEL_FORMAT_UNKNOWN";
|
36
|
+
}
|
37
|
+
|
18
38
|
/** Abstract camera image base class.
|
19
39
|
* Encapsulates the JPEG encoded data and it is shared among
|
20
40
|
* all connected clients.
|
@@ -43,6 +63,29 @@ class CameraImageReader {
|
|
43
63
|
virtual ~CameraImageReader() {}
|
44
64
|
};
|
45
65
|
|
66
|
+
/// Specification of a caputured camera image.
|
67
|
+
/// This struct defines the format and size details for images captured
|
68
|
+
/// or processed by a camera component.
|
69
|
+
struct CameraImageSpec {
|
70
|
+
uint16_t width;
|
71
|
+
uint16_t height;
|
72
|
+
PixelFormat format;
|
73
|
+
size_t bytes_per_pixel() {
|
74
|
+
switch (format) {
|
75
|
+
case PIXEL_FORMAT_GRAYSCALE:
|
76
|
+
return 1;
|
77
|
+
case PIXEL_FORMAT_RGB565:
|
78
|
+
return 2;
|
79
|
+
case PIXEL_FORMAT_BGR888:
|
80
|
+
return 3;
|
81
|
+
}
|
82
|
+
|
83
|
+
return 1;
|
84
|
+
}
|
85
|
+
size_t bytes_per_row() { return bytes_per_pixel() * width; }
|
86
|
+
size_t bytes_per_image() { return bytes_per_pixel() * width * height; }
|
87
|
+
};
|
88
|
+
|
46
89
|
/** Abstract camera base class. Collaborates with API.
|
47
90
|
* 1) API server starts and installs callback (add_image_callback)
|
48
91
|
* which is called by the camera when a new image is available.
|