esphome 2025.8.4__py3-none-any.whl → 2025.9.0b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- esphome/__main__.py +36 -42
- esphome/components/absolute_humidity/absolute_humidity.cpp +3 -5
- esphome/components/adc/adc_sensor_esp32.cpp +29 -6
- 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 +34 -23
- esphome/components/api/api_connection.h +20 -39
- 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 +20 -2
- esphome/components/api/api_pb2.h +146 -141
- esphome/components/api/api_pb2_dump.cpp +12 -1
- 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 +3 -2
- 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_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_client/ble_client_base.cpp +7 -3
- esphome/components/esp32_ble_tracker/__init__.py +2 -2
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +9 -44
- 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 +7 -2
- esphome/components/ethernet/ethernet_component.cpp +1 -1
- esphome/components/event/__init__.py +2 -2
- esphome/components/event/event.h +4 -4
- 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/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/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_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/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.h +2 -2
- 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/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 +3 -3
- esphome/components/wifi/wifi_component_esp_idf.cpp +2 -0
- esphome/config_validation.py +2 -2
- esphome/const.py +2 -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 +4 -0
- esphome/core/entity_base.cpp +22 -8
- esphome/core/entity_base.h +43 -0
- esphome/core/helpers.cpp +26 -13
- esphome/core/helpers.h +4 -3
- esphome/core/ring_buffer.cpp +6 -2
- esphome/core/ring_buffer.h +2 -1
- esphome/core/scheduler.cpp +175 -94
- esphome/core/scheduler.h +66 -35
- 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 +67 -10
- esphome/espota2.py +13 -6
- esphome/helpers.py +68 -83
- esphome/resolver.py +67 -0
- esphome/util.py +9 -6
- esphome/wizard.py +39 -26
- {esphome-2025.8.4.dist-info → esphome-2025.9.0b1.dist-info}/METADATA +9 -9
- {esphome-2025.8.4.dist-info → esphome-2025.9.0b1.dist-info}/RECORD +344 -313
- /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.0b1.dist-info}/WHEEL +0 -0
- {esphome-2025.8.4.dist-info → esphome-2025.9.0b1.dist-info}/entry_points.txt +0 -0
- {esphome-2025.8.4.dist-info → esphome-2025.9.0b1.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.8.4.dist-info → esphome-2025.9.0b1.dist-info}/top_level.txt +0 -0
@@ -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();
|
@@ -161,7 +161,8 @@ class BluetoothProxy : public esp32_ble_tracker::ESPBTDeviceListener, public Com
|
|
161
161
|
// Group 4: 1-byte types grouped together
|
162
162
|
bool active_;
|
163
163
|
uint8_t connection_count_{0};
|
164
|
-
//
|
164
|
+
bool configured_scan_active_{false}; // Configured scan mode from YAML
|
165
|
+
// 3 bytes used, 1 byte padding
|
165
166
|
};
|
166
167
|
|
167
168
|
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.
|
@@ -0,0 +1,69 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "buffer.h"
|
4
|
+
#include "camera.h"
|
5
|
+
|
6
|
+
namespace esphome::camera {
|
7
|
+
|
8
|
+
/// Result codes from the encoder used to control camera pipeline flow.
|
9
|
+
enum EncoderError : uint8_t {
|
10
|
+
ENCODER_ERROR_SUCCESS = 0, ///< Encoding succeeded, continue pipeline normally.
|
11
|
+
ENCODER_ERROR_SKIP_FRAME, ///< Skip current frame, try again on next frame.
|
12
|
+
ENCODER_ERROR_RETRY_FRAME, ///< Retry current frame, after buffer growth or for incremental encoding.
|
13
|
+
ENCODER_ERROR_CONFIGURATION ///< Fatal config error, shut down pipeline.
|
14
|
+
};
|
15
|
+
|
16
|
+
/// Converts EncoderError to string.
|
17
|
+
inline const char *to_string(EncoderError error) {
|
18
|
+
switch (error) {
|
19
|
+
case ENCODER_ERROR_SUCCESS:
|
20
|
+
return "ENCODER_ERROR_SUCCESS";
|
21
|
+
case ENCODER_ERROR_SKIP_FRAME:
|
22
|
+
return "ENCODER_ERROR_SKIP_FRAME";
|
23
|
+
case ENCODER_ERROR_RETRY_FRAME:
|
24
|
+
return "ENCODER_ERROR_RETRY_FRAME";
|
25
|
+
case ENCODER_ERROR_CONFIGURATION:
|
26
|
+
return "ENCODER_ERROR_CONFIGURATION";
|
27
|
+
}
|
28
|
+
return "ENCODER_ERROR_INVALID";
|
29
|
+
}
|
30
|
+
|
31
|
+
/// Interface for an encoder buffer supporting resizing and variable-length data.
|
32
|
+
class EncoderBuffer {
|
33
|
+
public:
|
34
|
+
/// Sets logical buffer size, reallocates if needed.
|
35
|
+
/// @param size Required size in bytes.
|
36
|
+
/// @return true on success, false on allocation failure.
|
37
|
+
virtual bool set_buffer_size(size_t size) = 0;
|
38
|
+
|
39
|
+
/// Returns a pointer to the buffer data.
|
40
|
+
virtual uint8_t *get_data() const = 0;
|
41
|
+
|
42
|
+
/// Returns number of bytes currently used.
|
43
|
+
virtual size_t get_size() const = 0;
|
44
|
+
|
45
|
+
/// Returns total allocated buffer size.
|
46
|
+
virtual size_t get_max_size() const = 0;
|
47
|
+
|
48
|
+
virtual ~EncoderBuffer() = default;
|
49
|
+
};
|
50
|
+
|
51
|
+
/// Interface for image encoders used in a camera pipeline.
|
52
|
+
class Encoder {
|
53
|
+
public:
|
54
|
+
/// Encodes pixel data from a previous camera pipeline stage.
|
55
|
+
/// @param spec Specification of the input pixel data.
|
56
|
+
/// @param pixels Image pixels in RGB or grayscale format, as specified in @p spec.
|
57
|
+
/// @return EncoderError Indicating the result of the encoding operation.
|
58
|
+
virtual EncoderError encode_pixels(CameraImageSpec *spec, Buffer *pixels) = 0;
|
59
|
+
|
60
|
+
/// Returns the encoder's output buffer.
|
61
|
+
/// @return Pointer to an EncoderBuffer containing encoded data.
|
62
|
+
virtual EncoderBuffer *get_output_buffer() = 0;
|
63
|
+
|
64
|
+
/// Prints the encoder's configuration to the log.
|
65
|
+
virtual void dump_config() = 0;
|
66
|
+
virtual ~Encoder() = default;
|
67
|
+
};
|
68
|
+
|
69
|
+
} // namespace esphome::camera
|
@@ -0,0 +1,62 @@
|
|
1
|
+
import esphome.codegen as cg
|
2
|
+
from esphome.components.esp32 import add_idf_component
|
3
|
+
import esphome.config_validation as cv
|
4
|
+
from esphome.const import CONF_BUFFER_SIZE, CONF_ID, CONF_TYPE
|
5
|
+
from esphome.core import CORE
|
6
|
+
from esphome.types import ConfigType
|
7
|
+
|
8
|
+
CODEOWNERS = ["@DT-art1"]
|
9
|
+
|
10
|
+
AUTO_LOAD = ["camera"]
|
11
|
+
|
12
|
+
CONF_BUFFER_EXPAND_SIZE = "buffer_expand_size"
|
13
|
+
CONF_ENCODER_BUFFER_ID = "encoder_buffer_id"
|
14
|
+
CONF_QUALITY = "quality"
|
15
|
+
|
16
|
+
ESP32_CAMERA_ENCODER = "esp32_camera"
|
17
|
+
|
18
|
+
camera_ns = cg.esphome_ns.namespace("camera")
|
19
|
+
camera_encoder_ns = cg.esphome_ns.namespace("camera_encoder")
|
20
|
+
|
21
|
+
Encoder = camera_ns.class_("Encoder")
|
22
|
+
EncoderBufferImpl = camera_encoder_ns.class_("EncoderBufferImpl")
|
23
|
+
|
24
|
+
ESP32CameraJPEGEncoder = camera_encoder_ns.class_("ESP32CameraJPEGEncoder", Encoder)
|
25
|
+
|
26
|
+
MAX_JPEG_BUFFER_SIZE_2MB = 2 * 1024 * 1024
|
27
|
+
|
28
|
+
ESP32_CAMERA_ENCODER_SCHEMA = cv.Schema(
|
29
|
+
{
|
30
|
+
cv.GenerateID(): cv.declare_id(ESP32CameraJPEGEncoder),
|
31
|
+
cv.Optional(CONF_QUALITY, default=80): cv.int_range(1, 100),
|
32
|
+
cv.Optional(CONF_BUFFER_SIZE, default=4096): cv.int_range(
|
33
|
+
1024, MAX_JPEG_BUFFER_SIZE_2MB
|
34
|
+
),
|
35
|
+
cv.Optional(CONF_BUFFER_EXPAND_SIZE, default=1024): cv.int_range(
|
36
|
+
0, MAX_JPEG_BUFFER_SIZE_2MB
|
37
|
+
),
|
38
|
+
cv.GenerateID(CONF_ENCODER_BUFFER_ID): cv.declare_id(EncoderBufferImpl),
|
39
|
+
}
|
40
|
+
)
|
41
|
+
|
42
|
+
CONFIG_SCHEMA = cv.typed_schema(
|
43
|
+
{
|
44
|
+
ESP32_CAMERA_ENCODER: ESP32_CAMERA_ENCODER_SCHEMA,
|
45
|
+
},
|
46
|
+
default_type=ESP32_CAMERA_ENCODER,
|
47
|
+
)
|
48
|
+
|
49
|
+
|
50
|
+
async def to_code(config: ConfigType) -> None:
|
51
|
+
buffer = cg.new_Pvariable(config[CONF_ENCODER_BUFFER_ID])
|
52
|
+
cg.add(buffer.set_buffer_size(config[CONF_BUFFER_SIZE]))
|
53
|
+
if config[CONF_TYPE] == ESP32_CAMERA_ENCODER:
|
54
|
+
if CORE.using_esp_idf:
|
55
|
+
add_idf_component(name="espressif/esp32-camera", ref="2.1.0")
|
56
|
+
cg.add_build_flag("-DUSE_ESP32_CAMERA_JPEG_ENCODER")
|
57
|
+
var = cg.new_Pvariable(
|
58
|
+
config[CONF_ID],
|
59
|
+
config[CONF_QUALITY],
|
60
|
+
buffer,
|
61
|
+
)
|
62
|
+
cg.add(var.set_buffer_expand_size(config[CONF_BUFFER_EXPAND_SIZE]))
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#include "encoder_buffer_impl.h"
|
2
|
+
|
3
|
+
namespace esphome::camera_encoder {
|
4
|
+
|
5
|
+
bool EncoderBufferImpl::set_buffer_size(size_t size) {
|
6
|
+
if (size > this->capacity_) {
|
7
|
+
uint8_t *p = this->allocator_.reallocate(this->data_, size);
|
8
|
+
if (p == nullptr)
|
9
|
+
return false;
|
10
|
+
|
11
|
+
this->data_ = p;
|
12
|
+
this->capacity_ = size;
|
13
|
+
}
|
14
|
+
this->size_ = size;
|
15
|
+
return true;
|
16
|
+
}
|
17
|
+
|
18
|
+
EncoderBufferImpl::~EncoderBufferImpl() {
|
19
|
+
if (this->data_ != nullptr)
|
20
|
+
this->allocator_.deallocate(this->data_, this->capacity_);
|
21
|
+
}
|
22
|
+
|
23
|
+
} // namespace esphome::camera_encoder
|
@@ -0,0 +1,25 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "esphome/components/camera/encoder.h"
|
4
|
+
#include "esphome/core/helpers.h"
|
5
|
+
|
6
|
+
namespace esphome::camera_encoder {
|
7
|
+
|
8
|
+
class EncoderBufferImpl : public camera::EncoderBuffer {
|
9
|
+
public:
|
10
|
+
// --- EncoderBuffer ---
|
11
|
+
bool set_buffer_size(size_t size) override;
|
12
|
+
uint8_t *get_data() const override { return this->data_; }
|
13
|
+
size_t get_size() const override { return this->size_; }
|
14
|
+
size_t get_max_size() const override { return this->capacity_; }
|
15
|
+
// ----------------------
|
16
|
+
~EncoderBufferImpl() override;
|
17
|
+
|
18
|
+
protected:
|
19
|
+
RAMAllocator<uint8_t> allocator_;
|
20
|
+
size_t capacity_{};
|
21
|
+
size_t size_{};
|
22
|
+
uint8_t *data_{};
|
23
|
+
};
|
24
|
+
|
25
|
+
} // namespace esphome::camera_encoder
|
@@ -0,0 +1,82 @@
|
|
1
|
+
#ifdef USE_ESP32_CAMERA_JPEG_ENCODER
|
2
|
+
|
3
|
+
#include "esp32_camera_jpeg_encoder.h"
|
4
|
+
|
5
|
+
namespace esphome::camera_encoder {
|
6
|
+
|
7
|
+
static const char *const TAG = "camera_encoder";
|
8
|
+
|
9
|
+
ESP32CameraJPEGEncoder::ESP32CameraJPEGEncoder(uint8_t quality, camera::EncoderBuffer *output) {
|
10
|
+
this->quality_ = quality;
|
11
|
+
this->output_ = output;
|
12
|
+
}
|
13
|
+
|
14
|
+
camera::EncoderError ESP32CameraJPEGEncoder::encode_pixels(camera::CameraImageSpec *spec, camera::Buffer *pixels) {
|
15
|
+
this->bytes_written_ = 0;
|
16
|
+
this->out_of_output_memory_ = false;
|
17
|
+
bool success = fmt2jpg_cb(pixels->get_data_buffer(), pixels->get_data_length(), spec->width, spec->height,
|
18
|
+
to_internal_(spec->format), this->quality_, callback_, this);
|
19
|
+
|
20
|
+
if (!success)
|
21
|
+
return camera::ENCODER_ERROR_CONFIGURATION;
|
22
|
+
|
23
|
+
if (this->out_of_output_memory_) {
|
24
|
+
if (this->buffer_expand_size_ <= 0)
|
25
|
+
return camera::ENCODER_ERROR_SKIP_FRAME;
|
26
|
+
|
27
|
+
size_t current_size = this->output_->get_max_size();
|
28
|
+
size_t new_size = this->output_->get_max_size() + this->buffer_expand_size_;
|
29
|
+
if (!this->output_->set_buffer_size(new_size)) {
|
30
|
+
ESP_LOGE(TAG, "Failed to expand output buffer.");
|
31
|
+
this->buffer_expand_size_ = 0;
|
32
|
+
return camera::ENCODER_ERROR_SKIP_FRAME;
|
33
|
+
}
|
34
|
+
|
35
|
+
ESP_LOGD(TAG, "Output buffer expanded (%u -> %u).", current_size, this->output_->get_max_size());
|
36
|
+
return camera::ENCODER_ERROR_RETRY_FRAME;
|
37
|
+
}
|
38
|
+
|
39
|
+
this->output_->set_buffer_size(this->bytes_written_);
|
40
|
+
return camera::ENCODER_ERROR_SUCCESS;
|
41
|
+
}
|
42
|
+
|
43
|
+
void ESP32CameraJPEGEncoder::dump_config() {
|
44
|
+
ESP_LOGCONFIG(TAG,
|
45
|
+
"ESP32 Camera JPEG Encoder:\n"
|
46
|
+
" Size: %zu\n"
|
47
|
+
" Quality: %d\n"
|
48
|
+
" Expand: %d\n",
|
49
|
+
this->output_->get_max_size(), this->quality_, this->buffer_expand_size_);
|
50
|
+
}
|
51
|
+
|
52
|
+
size_t ESP32CameraJPEGEncoder::callback_(void *arg, size_t index, const void *data, size_t len) {
|
53
|
+
ESP32CameraJPEGEncoder *that = reinterpret_cast<ESP32CameraJPEGEncoder *>(arg);
|
54
|
+
uint8_t *buffer = that->output_->get_data();
|
55
|
+
size_t buffer_length = that->output_->get_max_size();
|
56
|
+
if (index + len > buffer_length) {
|
57
|
+
that->out_of_output_memory_ = true;
|
58
|
+
return 0;
|
59
|
+
}
|
60
|
+
|
61
|
+
std::memcpy(&buffer[index], data, len);
|
62
|
+
that->bytes_written_ += len;
|
63
|
+
return len;
|
64
|
+
}
|
65
|
+
|
66
|
+
pixformat_t ESP32CameraJPEGEncoder::to_internal_(camera::PixelFormat format) {
|
67
|
+
switch (format) {
|
68
|
+
case camera::PIXEL_FORMAT_GRAYSCALE:
|
69
|
+
return PIXFORMAT_GRAYSCALE;
|
70
|
+
case camera::PIXEL_FORMAT_RGB565:
|
71
|
+
return PIXFORMAT_RGB565;
|
72
|
+
// Internal representation for RGB is in byte order: B, G, R
|
73
|
+
case camera::PIXEL_FORMAT_BGR888:
|
74
|
+
return PIXFORMAT_RGB888;
|
75
|
+
}
|
76
|
+
|
77
|
+
return PIXFORMAT_GRAYSCALE;
|
78
|
+
}
|
79
|
+
|
80
|
+
} // namespace esphome::camera_encoder
|
81
|
+
|
82
|
+
#endif
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#ifdef USE_ESP32_CAMERA_JPEG_ENCODER
|
4
|
+
|
5
|
+
#include <esp_camera.h>
|
6
|
+
|
7
|
+
#include "esphome/components/camera/encoder.h"
|
8
|
+
|
9
|
+
namespace esphome::camera_encoder {
|
10
|
+
|
11
|
+
/// Encoder that uses the software-based JPEG implementation from Espressif's esp32-camera component.
|
12
|
+
class ESP32CameraJPEGEncoder : public camera::Encoder {
|
13
|
+
public:
|
14
|
+
/// Constructs a ESP32CameraJPEGEncoder instance.
|
15
|
+
/// @param quality Sets the quality of the encoded image (1-100).
|
16
|
+
/// @param output Pointer to preallocated output buffer.
|
17
|
+
ESP32CameraJPEGEncoder(uint8_t quality, camera::EncoderBuffer *output);
|
18
|
+
/// Sets the number of bytes to expand the output buffer on underflow during encoding.
|
19
|
+
/// @param buffer_expand_size Number of bytes to expand the buffer.
|
20
|
+
void set_buffer_expand_size(size_t buffer_expand_size) { this->buffer_expand_size_ = buffer_expand_size; }
|
21
|
+
// -------- Encoder --------
|
22
|
+
camera::EncoderError encode_pixels(camera::CameraImageSpec *spec, camera::Buffer *pixels) override;
|
23
|
+
camera::EncoderBuffer *get_output_buffer() override { return output_; }
|
24
|
+
void dump_config() override;
|
25
|
+
// -------------------------
|
26
|
+
protected:
|
27
|
+
static size_t callback_(void *arg, size_t index, const void *data, size_t len);
|
28
|
+
pixformat_t to_internal_(camera::PixelFormat format);
|
29
|
+
|
30
|
+
camera::EncoderBuffer *output_{};
|
31
|
+
size_t buffer_expand_size_{};
|
32
|
+
size_t bytes_written_{};
|
33
|
+
uint8_t quality_{};
|
34
|
+
bool out_of_output_memory_{};
|
35
|
+
};
|
36
|
+
|
37
|
+
} // namespace esphome::camera_encoder
|
38
|
+
|
39
|
+
#endif
|
@@ -10,7 +10,7 @@ from esphome.const import (
|
|
10
10
|
PLATFORM_LN882X,
|
11
11
|
PLATFORM_RTL87XX,
|
12
12
|
)
|
13
|
-
from esphome.core import CORE, coroutine_with_priority
|
13
|
+
from esphome.core import CORE, CoroPriority, coroutine_with_priority
|
14
14
|
|
15
15
|
AUTO_LOAD = ["web_server_base", "ota.web_server"]
|
16
16
|
DEPENDENCIES = ["wifi"]
|
@@ -40,7 +40,7 @@ CONFIG_SCHEMA = cv.All(
|
|
40
40
|
)
|
41
41
|
|
42
42
|
|
43
|
-
@coroutine_with_priority(
|
43
|
+
@coroutine_with_priority(CoroPriority.COMMUNICATION)
|
44
44
|
async def to_code(config):
|
45
45
|
paren = await cg.get_variable(config[CONF_WEB_SERVER_BASE_ID])
|
46
46
|
|