esphome 2025.4.1__py3-none-any.whl → 2025.5.0b2__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/components/ac_dimmer/ac_dimmer.cpp +3 -2
- esphome/components/adc/__init__.py +51 -34
- esphome/components/airthings_wave_base/__init__.py +1 -1
- esphome/components/alarm_control_panel/__init__.py +37 -2
- esphome/components/am43/cover/__init__.py +4 -5
- esphome/components/analog_threshold/analog_threshold_binary_sensor.cpp +6 -4
- esphome/components/analog_threshold/analog_threshold_binary_sensor.h +4 -5
- esphome/components/analog_threshold/binary_sensor.py +10 -8
- esphome/components/anova/climate.py +4 -5
- esphome/components/api/__init__.py +25 -8
- esphome/components/api/api_connection.cpp +77 -10
- esphome/components/api/api_connection.h +6 -1
- esphome/components/api/api_frame_helper.cpp +98 -130
- esphome/components/api/api_frame_helper.h +12 -2
- esphome/components/api/api_noise_context.h +13 -4
- esphome/components/api/api_pb2.cpp +1422 -1
- esphome/components/api/api_pb2.h +255 -1
- esphome/components/api/api_pb2_service.cpp +162 -49
- esphome/components/api/api_pb2_service.h +90 -51
- esphome/components/api/api_pb2_size.h +361 -0
- esphome/components/api/api_server.cpp +110 -34
- esphome/components/api/api_server.h +8 -0
- esphome/components/api/proto.h +38 -9
- esphome/components/as3935_i2c/as3935_i2c.h +0 -3
- esphome/components/as7341/as7341.h +1 -1
- esphome/components/atm90e32/__init__.py +1 -0
- esphome/components/atm90e32/atm90e32.cpp +576 -199
- esphome/components/atm90e32/atm90e32.h +128 -31
- esphome/components/atm90e32/atm90e32_reg.h +4 -2
- esphome/components/atm90e32/button/__init__.py +62 -10
- esphome/components/atm90e32/button/atm90e32_button.cpp +63 -4
- esphome/components/atm90e32/button/atm90e32_button.h +36 -4
- esphome/components/atm90e32/number/__init__.py +130 -0
- esphome/components/atm90e32/number/atm90e32_number.h +16 -0
- esphome/components/atm90e32/sensor.py +21 -4
- esphome/components/atm90e32/text_sensor/__init__.py +48 -0
- esphome/components/audio/__init__.py +96 -49
- esphome/components/audio/audio.h +48 -0
- esphome/components/audio/audio_decoder.cpp +1 -1
- esphome/components/audio/audio_resampler.cpp +2 -0
- esphome/components/audio/audio_resampler.h +1 -0
- esphome/components/ballu/climate.py +2 -9
- esphome/components/bang_bang/climate.py +5 -6
- esphome/components/bedjet/climate/__init__.py +3 -8
- esphome/components/bedjet/fan/__init__.py +2 -11
- esphome/components/binary/fan/__init__.py +13 -16
- esphome/components/binary_sensor/__init__.py +13 -10
- esphome/components/binary_sensor/binary_sensor.cpp +6 -10
- esphome/components/binary_sensor/binary_sensor.h +1 -1
- esphome/components/binary_sensor/filter.cpp +21 -21
- esphome/components/binary_sensor/filter.h +10 -10
- esphome/components/bl0906/constants.h +16 -16
- esphome/components/ble_client/text_sensor/__init__.py +3 -5
- esphome/components/bluetooth_proxy/bluetooth_connection.cpp +4 -6
- esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +135 -21
- esphome/components/bluetooth_proxy/bluetooth_proxy.h +7 -0
- esphome/components/button/__init__.py +11 -8
- esphome/components/canbus/canbus.cpp +3 -0
- esphome/components/canbus/canbus.h +16 -0
- esphome/components/climate/__init__.py +35 -2
- esphome/components/climate/climate_mode.h +1 -1
- esphome/components/climate/climate_traits.h +63 -57
- esphome/components/climate_ir/__init__.py +57 -17
- esphome/components/climate_ir_lg/climate.py +2 -5
- esphome/components/climate_ir_lg/climate_ir_lg.cpp +7 -7
- esphome/components/climate_ir_lg/climate_ir_lg.h +1 -1
- esphome/components/color/__init__.py +2 -0
- esphome/components/const/__init__.py +5 -0
- esphome/components/coolix/climate.py +2 -9
- esphome/components/copy/cover/__init__.py +10 -9
- esphome/components/copy/fan/__init__.py +11 -9
- esphome/components/copy/lock/__init__.py +11 -9
- esphome/components/copy/text/__init__.py +9 -6
- esphome/components/cover/__init__.py +37 -2
- esphome/components/cst226/binary_sensor/__init__.py +28 -0
- esphome/components/cst226/binary_sensor/cs226_button.h +22 -0
- esphome/components/cst226/binary_sensor/cstt6_button.cpp +19 -0
- esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +27 -5
- esphome/components/cst226/touchscreen/cst226_touchscreen.h +10 -10
- esphome/components/current_based/cover.py +37 -36
- esphome/components/daikin/climate.py +2 -9
- esphome/components/daikin/daikin.cpp +15 -9
- esphome/components/daikin/daikin.h +5 -5
- esphome/components/daikin_arc/climate.py +2 -7
- esphome/components/daikin_brc/climate.py +3 -5
- esphome/components/dallas_temp/dallas_temp.cpp +17 -24
- esphome/components/dallas_temp/dallas_temp.h +0 -1
- esphome/components/debug/debug_component.cpp +5 -0
- esphome/components/debug/debug_component.h +6 -0
- esphome/components/debug/debug_esp32.cpp +109 -254
- esphome/components/debug/sensor.py +14 -0
- esphome/components/deep_sleep/deep_sleep_esp32.cpp +13 -1
- esphome/components/delonghi/climate.py +2 -9
- esphome/components/demo/__init__.py +18 -20
- esphome/components/dfrobot_sen0395/switch/__init__.py +21 -22
- esphome/components/display/rect.cpp +4 -9
- esphome/components/display/rect.h +1 -1
- esphome/components/emmeti/climate.py +2 -9
- esphome/components/endstop/cover.py +17 -16
- esphome/components/esp32/__init__.py +60 -3
- esphome/components/esp32/core.cpp +11 -5
- esphome/components/esp32/gpio.cpp +86 -24
- esphome/components/esp32/gpio.py +15 -16
- esphome/components/esp32/gpio_esp32.py +1 -2
- esphome/components/esp32/gpio_esp32_c2.py +1 -1
- esphome/components/esp32/gpio_esp32_c3.py +1 -1
- esphome/components/esp32/gpio_esp32_c6.py +1 -1
- esphome/components/esp32/gpio_esp32_h2.py +1 -1
- esphome/components/esp32_ble/ble.cpp +1 -8
- esphome/components/esp32_ble/ble.h +5 -3
- esphome/components/esp32_ble/ble_advertising.h +1 -0
- esphome/components/esp32_ble_server/__init__.py +3 -0
- esphome/components/esp32_ble_tracker/__init__.py +7 -1
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +192 -118
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +29 -3
- esphome/components/esp32_can/esp32_can.cpp +1 -1
- esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
- esphome/components/esp32_rmt_led_strip/led_strip.h +7 -5
- esphome/components/esp32_rmt_led_strip/light.py +9 -1
- esphome/components/esp8266/gpio.cpp +69 -8
- esphome/components/event/__init__.py +13 -10
- esphome/components/factory_reset/switch/__init__.py +7 -21
- esphome/components/fan/__init__.py +52 -5
- esphome/components/fastled_base/__init__.py +1 -4
- esphome/components/fastled_base/fastled_light.cpp +1 -1
- esphome/components/feedback/cover.py +38 -33
- esphome/components/fujitsu_general/climate.py +2 -9
- esphome/components/gpio/one_wire/gpio_one_wire.cpp +45 -43
- esphome/components/gpio/one_wire/gpio_one_wire.h +2 -1
- esphome/components/gpio_expander/cached_gpio.h +22 -7
- esphome/components/gps/__init__.py +11 -2
- esphome/components/gps/gps.cpp +11 -8
- esphome/components/gps/gps.h +9 -6
- esphome/components/graph/__init__.py +1 -2
- esphome/components/gree/climate.py +4 -6
- esphome/components/gree/gree.cpp +16 -2
- esphome/components/gree/gree.h +2 -2
- esphome/components/haier/climate.py +37 -34
- esphome/components/hbridge/fan/__init__.py +19 -17
- esphome/components/he60r/cover.py +4 -5
- esphome/components/heatpumpir/climate.py +3 -6
- esphome/components/hitachi_ac344/climate.py +2 -9
- esphome/components/hitachi_ac424/climate.py +2 -9
- esphome/components/hlw8012/hlw8012.cpp +1 -1
- esphome/components/hm3301/hm3301.h +1 -1
- esphome/components/http_request/__init__.py +39 -6
- esphome/components/http_request/http_request.cpp +20 -0
- esphome/components/http_request/http_request.h +57 -15
- esphome/components/http_request/http_request_arduino.cpp +22 -6
- esphome/components/http_request/http_request_arduino.h +4 -3
- esphome/components/http_request/http_request_host.cpp +141 -0
- esphome/components/http_request/http_request_host.h +37 -0
- esphome/components/http_request/http_request_idf.cpp +35 -3
- esphome/components/http_request/http_request_idf.h +10 -3
- esphome/components/http_request/httplib.h +9691 -0
- esphome/components/http_request/update/__init__.py +11 -8
- esphome/components/i2c/i2c.h +4 -0
- esphome/components/i2c/i2c_bus_esp_idf.cpp +1 -1
- esphome/components/i2s_audio/__init__.py +131 -22
- esphome/components/i2s_audio/i2s_audio.h +44 -4
- esphome/components/i2s_audio/media_player/__init__.py +19 -9
- esphome/components/i2s_audio/microphone/__init__.py +63 -5
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +351 -61
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +40 -6
- esphome/components/i2s_audio/speaker/__init__.py +31 -5
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +155 -19
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +17 -4
- esphome/components/ili9xxx/ili9xxx_init.h +1 -1
- esphome/components/image/__init__.py +37 -17
- esphome/components/image/image.cpp +25 -8
- esphome/components/internal_temperature/internal_temperature.cpp +6 -4
- esphome/components/key_collector/__init__.py +35 -0
- esphome/components/key_collector/key_collector.cpp +8 -0
- esphome/components/key_collector/key_collector.h +10 -0
- esphome/components/ld2410/ld2410.h +1 -1
- esphome/components/ld2450/ld2450.h +1 -1
- esphome/components/light/__init__.py +57 -0
- esphome/components/lock/__init__.py +51 -4
- esphome/components/lock/automation.h +2 -13
- esphome/components/logger/__init__.py +21 -0
- esphome/components/logger/logger.cpp +125 -95
- esphome/components/logger/logger.h +160 -35
- esphome/components/logger/task_log_buffer.cpp +138 -0
- esphome/components/logger/task_log_buffer.h +69 -0
- esphome/components/lvgl/__init__.py +13 -5
- esphome/components/lvgl/automation.py +50 -1
- esphome/components/lvgl/defines.py +0 -1
- esphome/components/lvgl/lv_validation.py +10 -1
- esphome/components/lvgl/lvgl_esphome.cpp +5 -1
- esphome/components/lvgl/schemas.py +14 -14
- esphome/components/lvgl/text/__init__.py +1 -2
- esphome/components/lvgl/widgets/arc.py +7 -6
- esphome/components/lvgl/widgets/buttonmatrix.py +3 -3
- esphome/components/lvgl/widgets/checkbox.py +2 -2
- esphome/components/lvgl/widgets/dropdown.py +2 -1
- esphome/components/lvgl/widgets/img.py +15 -12
- esphome/components/mapping/__init__.py +134 -0
- esphome/components/max7219digit/max7219digit.cpp +27 -27
- esphome/components/mdns/__init__.py +11 -5
- esphome/components/mdns/mdns_component.cpp +11 -5
- esphome/components/mdns/mdns_component.h +3 -2
- esphome/components/mdns/mdns_esp32.cpp +4 -3
- esphome/components/mdns/mdns_esp8266.cpp +4 -2
- esphome/components/mdns/mdns_libretiny.cpp +4 -2
- esphome/components/mdns/mdns_rp2040.cpp +4 -2
- esphome/components/media_player/__init__.py +40 -6
- esphome/components/micro_wake_word/__init__.py +99 -31
- esphome/components/micro_wake_word/automation.h +54 -0
- esphome/components/micro_wake_word/micro_wake_word.cpp +331 -319
- esphome/components/micro_wake_word/micro_wake_word.h +58 -105
- esphome/components/micro_wake_word/preprocessor_settings.h +19 -2
- esphome/components/micro_wake_word/streaming_model.cpp +158 -41
- esphome/components/micro_wake_word/streaming_model.h +85 -13
- esphome/components/microphone/__init__.py +139 -9
- esphome/components/microphone/automation.h +14 -2
- esphome/components/microphone/microphone.cpp +21 -0
- esphome/components/microphone/microphone.h +14 -5
- esphome/components/microphone/microphone_source.cpp +95 -0
- esphome/components/microphone/microphone_source.h +80 -0
- esphome/components/mics_4514/sensor.py +25 -14
- esphome/components/midea/climate.py +3 -4
- esphome/components/midea_ir/climate.py +3 -5
- esphome/components/mipi_spi/__init__.py +15 -0
- esphome/components/mipi_spi/display.py +474 -0
- esphome/components/mipi_spi/mipi_spi.cpp +481 -0
- esphome/components/mipi_spi/mipi_spi.h +171 -0
- esphome/components/mipi_spi/models/__init__.py +65 -0
- esphome/components/mipi_spi/models/amoled.py +72 -0
- esphome/components/mipi_spi/models/commands.py +82 -0
- esphome/components/mipi_spi/models/cyd.py +10 -0
- esphome/components/mipi_spi/models/ili.py +749 -0
- esphome/components/mipi_spi/models/jc.py +260 -0
- esphome/components/mipi_spi/models/lanbon.py +15 -0
- esphome/components/mipi_spi/models/lilygo.py +60 -0
- esphome/components/mipi_spi/models/waveshare.py +139 -0
- esphome/components/mitsubishi/climate.py +2 -5
- esphome/components/mitsubishi/mitsubishi.cpp +9 -9
- esphome/components/mixer/speaker/mixer_speaker.cpp +12 -22
- esphome/components/mixer/speaker/mixer_speaker.h +1 -3
- esphome/components/mlx90393/sensor.py +5 -0
- esphome/components/mlx90393/sensor_mlx90393.cpp +195 -13
- esphome/components/mlx90393/sensor_mlx90393.h +21 -4
- esphome/components/mqtt/__init__.py +1 -1
- esphome/components/mqtt/mqtt_client.cpp +5 -1
- esphome/components/mqtt/mqtt_const.h +4 -0
- esphome/components/mqtt/mqtt_fan.cpp +39 -0
- esphome/components/mqtt/mqtt_fan.h +2 -0
- esphome/components/network/__init__.py +1 -1
- esphome/components/nextion/base_component.py +17 -16
- esphome/components/nextion/display.py +11 -2
- esphome/components/nextion/nextion.cpp +39 -1
- esphome/components/nextion/nextion.h +50 -0
- esphome/components/noblex/climate.py +2 -9
- esphome/components/number/__init__.py +12 -9
- esphome/components/one_wire/one_wire_bus.cpp +14 -10
- esphome/components/one_wire/one_wire_bus.h +14 -8
- esphome/components/online_image/bmp_image.cpp +48 -11
- esphome/components/online_image/bmp_image.h +2 -0
- esphome/components/opentherm/binary_sensor/__init__.py +2 -4
- esphome/components/opentherm/number/__init__.py +11 -20
- esphome/components/opentherm/sensor/__init__.py +3 -3
- esphome/components/opentherm/switch/__init__.py +3 -5
- esphome/components/output/lock/__init__.py +11 -9
- esphome/components/packages/__init__.py +33 -31
- esphome/components/packet_transport/__init__.py +201 -0
- esphome/components/packet_transport/binary_sensor.py +19 -0
- esphome/components/packet_transport/packet_transport.cpp +534 -0
- esphome/components/packet_transport/packet_transport.h +154 -0
- esphome/components/packet_transport/sensor.py +19 -0
- esphome/components/pca9685/pca9685_output.cpp +2 -1
- esphome/components/pid/climate.py +2 -4
- esphome/components/pm2005/__init__.py +1 -0
- esphome/components/pm2005/pm2005.cpp +123 -0
- esphome/components/pm2005/pm2005.h +46 -0
- esphome/components/pm2005/sensor.py +86 -0
- esphome/components/pmsa003i/pmsa003i.cpp +43 -16
- esphome/components/pmsa003i/pmsa003i.h +25 -25
- esphome/components/pmsx003/pmsx003.cpp +193 -229
- esphome/components/pmsx003/pmsx003.h +51 -33
- esphome/components/pmsx003/sensor.py +21 -11
- esphome/components/pn7150/pn7150.h +2 -2
- esphome/components/pn7160/pn7160.h +2 -2
- esphome/components/prometheus/prometheus_handler.cpp +174 -0
- esphome/components/prometheus/prometheus_handler.h +17 -0
- esphome/components/psram/__init__.py +7 -5
- esphome/components/pulse_meter/pulse_meter_sensor.cpp +32 -12
- esphome/components/pulse_meter/pulse_meter_sensor.h +5 -5
- esphome/components/qspi_dbi/__init__.py +0 -1
- esphome/components/qspi_dbi/display.py +2 -1
- esphome/components/qspi_dbi/models.py +1 -2
- esphome/components/remote_base/__init__.py +91 -0
- esphome/components/remote_base/beo4_protocol.cpp +153 -0
- esphome/components/remote_base/beo4_protocol.h +43 -0
- esphome/components/remote_base/gobox_protocol.cpp +131 -0
- esphome/components/remote_base/gobox_protocol.h +54 -0
- esphome/components/remote_receiver/remote_receiver_esp32.cpp +16 -9
- esphome/components/resampler/speaker/resampler_speaker.cpp +12 -10
- esphome/components/resampler/speaker/resampler_speaker.h +1 -1
- esphome/components/scd30/sensor.py +2 -3
- esphome/components/scd4x/sensor.py +4 -5
- esphome/components/sdp3x/sensor.py +2 -1
- esphome/components/select/__init__.py +19 -20
- esphome/components/sen5x/sensor.py +1 -1
- esphome/components/sensor/__init__.py +158 -14
- esphome/components/sensor/filter.cpp +23 -0
- esphome/components/sensor/filter.h +22 -0
- esphome/components/sgp4x/sensor.py +1 -1
- esphome/components/sht4x/sht4x.cpp +43 -22
- esphome/components/sht4x/sht4x.h +1 -1
- esphome/components/sml/text_sensor/__init__.py +4 -6
- esphome/components/sound_level/__init__.py +0 -0
- esphome/components/sound_level/sensor.py +97 -0
- esphome/components/sound_level/sound_level.cpp +194 -0
- esphome/components/sound_level/sound_level.h +73 -0
- esphome/components/speaker/media_player/__init__.py +4 -8
- esphome/components/speaker/media_player/speaker_media_player.cpp +0 -18
- esphome/components/speaker/media_player/speaker_media_player.h +0 -11
- esphome/components/speaker/speaker.h +4 -7
- esphome/components/speed/fan/__init__.py +17 -16
- esphome/components/spi/spi.h +11 -1
- esphome/components/sprinkler/__init__.py +18 -19
- esphome/components/switch/__init__.py +32 -42
- esphome/components/syslog/__init__.py +41 -0
- esphome/components/syslog/esphome_syslog.cpp +49 -0
- esphome/components/syslog/esphome_syslog.h +27 -0
- esphome/components/tca9555/tca9555.cpp +11 -6
- esphome/components/tcl112/climate.py +2 -9
- esphome/components/template/alarm_control_panel/__init__.py +7 -6
- esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +21 -17
- esphome/components/template/alarm_control_panel/template_alarm_control_panel.h +2 -1
- esphome/components/template/cover/__init__.py +27 -21
- esphome/components/template/fan/__init__.py +14 -12
- esphome/components/template/lock/__init__.py +20 -25
- esphome/components/template/lock/automation.h +18 -0
- esphome/components/template/text/__init__.py +4 -3
- esphome/components/template/valve/__init__.py +32 -21
- esphome/components/template/valve/automation.h +24 -0
- esphome/components/text/__init__.py +32 -1
- esphome/components/text_sensor/__init__.py +24 -29
- esphome/components/thermostat/climate.py +5 -5
- esphome/components/time_based/cover.py +17 -16
- esphome/components/tm1638/switch/__init__.py +10 -7
- esphome/components/tormatic/cover.py +4 -5
- esphome/components/toshiba/climate.py +3 -5
- esphome/components/touchscreen/touchscreen.cpp +3 -1
- esphome/components/tt21100/touchscreen/tt21100.cpp +1 -1
- esphome/components/tuya/climate/__init__.py +5 -6
- esphome/components/tuya/cover/__init__.py +6 -11
- esphome/components/tuya/select/__init__.py +15 -5
- esphome/components/tuya/select/tuya_select.cpp +6 -1
- esphome/components/tuya/select/tuya_select.h +5 -1
- esphome/components/uart/packet_transport/__init__.py +20 -0
- esphome/components/uart/packet_transport/uart_transport.cpp +88 -0
- esphome/components/uart/packet_transport/uart_transport.h +41 -0
- esphome/components/udp/__init__.py +126 -128
- esphome/components/udp/automation.h +40 -0
- esphome/components/udp/binary_sensor.py +3 -25
- esphome/components/udp/packet_transport/__init__.py +29 -0
- esphome/components/udp/packet_transport/udp_transport.cpp +36 -0
- esphome/components/udp/packet_transport/udp_transport.h +28 -0
- esphome/components/udp/sensor.py +3 -25
- esphome/components/udp/udp_component.cpp +26 -470
- esphome/components/udp/udp_component.h +21 -128
- esphome/components/update/__init__.py +31 -1
- esphome/components/uponor_smatrix/climate/__init__.py +4 -9
- esphome/components/uptime/text_sensor/__init__.py +47 -7
- esphome/components/uptime/text_sensor/uptime_text_sensor.cpp +12 -7
- esphome/components/uptime/text_sensor/uptime_text_sensor.h +19 -0
- esphome/components/valve/__init__.py +34 -3
- esphome/components/valve/automation.h +1 -19
- esphome/components/vl53l0x/sensor.py +11 -0
- esphome/components/vl53l0x/vl53l0x_sensor.cpp +5 -1
- esphome/components/vl53l0x/vl53l0x_sensor.h +2 -1
- esphome/components/voice_assistant/__init__.py +36 -10
- esphome/components/voice_assistant/voice_assistant.cpp +170 -144
- esphome/components/voice_assistant/voice_assistant.h +26 -25
- esphome/components/waveshare_epaper/display.py +6 -0
- esphome/components/waveshare_epaper/waveshare_epaper.cpp +439 -37
- esphome/components/waveshare_epaper/waveshare_epaper.h +60 -11
- esphome/components/whirlpool/climate.py +3 -5
- esphome/components/whynter/climate.py +3 -5
- esphome/components/xpt2046/touchscreen/xpt2046.cpp +1 -1
- esphome/components/yashima/climate.py +6 -6
- esphome/components/zhlt01/climate.py +2 -7
- esphome/config_validation.py +38 -58
- esphome/const.py +15 -1
- esphome/core/__init__.py +2 -0
- esphome/core/application.cpp +1 -0
- esphome/core/application.h +4 -0
- esphome/core/automation.h +4 -3
- esphome/core/component.cpp +19 -3
- esphome/core/component.h +5 -0
- esphome/core/defines.h +23 -17
- esphome/core/macros.h +4 -0
- esphome/core/scheduler.cpp +3 -0
- esphome/cpp_generator.py +6 -2
- esphome/dashboard/web_server.py +3 -3
- esphome/helpers.py +39 -0
- esphome/loader.py +4 -0
- esphome/mqtt.py +21 -8
- esphome/platformio_api.py +1 -1
- esphome/schema_extractors.py +0 -1
- esphome/vscode.py +15 -0
- esphome/wizard.py +2 -2
- esphome/zeroconf.py +7 -3
- {esphome-2025.4.1.dist-info → esphome-2025.5.0b2.dist-info}/METADATA +10 -11
- {esphome-2025.4.1.dist-info → esphome-2025.5.0b2.dist-info}/RECORD +411 -352
- {esphome-2025.4.1.dist-info → esphome-2025.5.0b2.dist-info}/WHEEL +1 -1
- esphome/components/esp32_ble/const_esp32c6.h +0 -74
- {esphome-2025.4.1.dist-info → esphome-2025.5.0b2.dist-info}/entry_points.txt +0 -0
- {esphome-2025.4.1.dist-info → esphome-2025.5.0b2.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.4.1.dist-info → esphome-2025.5.0b2.dist-info}/top_level.txt +0 -0
@@ -16,14 +16,17 @@ HttpRequestUpdate = http_request_ns.class_(
|
|
16
16
|
|
17
17
|
CONF_OTA_ID = "ota_id"
|
18
18
|
|
19
|
-
CONFIG_SCHEMA =
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
19
|
+
CONFIG_SCHEMA = (
|
20
|
+
update.update_schema(HttpRequestUpdate)
|
21
|
+
.extend(
|
22
|
+
{
|
23
|
+
cv.GenerateID(CONF_OTA_ID): cv.use_id(OtaHttpRequestComponent),
|
24
|
+
cv.GenerateID(CONF_HTTP_REQUEST_ID): cv.use_id(HttpRequestComponent),
|
25
|
+
cv.Required(CONF_SOURCE): cv.url,
|
26
|
+
}
|
27
|
+
)
|
28
|
+
.extend(cv.polling_component_schema("6h"))
|
29
|
+
)
|
27
30
|
|
28
31
|
|
29
32
|
async def to_code(config):
|
esphome/components/i2c/i2c.h
CHANGED
@@ -139,6 +139,10 @@ class I2CDevice {
|
|
139
139
|
/// @param address of the device
|
140
140
|
void set_i2c_address(uint8_t address) { address_ = address; }
|
141
141
|
|
142
|
+
/// @brief Returns the I2C address of the object.
|
143
|
+
/// @return the I2C address
|
144
|
+
uint8_t get_i2c_address() const { return this->address_; }
|
145
|
+
|
142
146
|
/// @brief we store the pointer to the I2CBus to use
|
143
147
|
/// @param bus pointer to the I2CBus object
|
144
148
|
void set_i2c_bus(I2CBus *bus) { bus_ = bus; }
|
@@ -67,7 +67,7 @@ void IDFI2CBus::setup() {
|
|
67
67
|
ESP_LOGV(TAG, "i2c_timeout set to %" PRIu32 " ticks (%" PRIu32 " us)", timeout_ * 80, timeout_);
|
68
68
|
}
|
69
69
|
}
|
70
|
-
err = i2c_driver_install(port_, I2C_MODE_MASTER, 0, 0,
|
70
|
+
err = i2c_driver_install(port_, I2C_MODE_MASTER, 0, 0, 0);
|
71
71
|
if (err != ESP_OK) {
|
72
72
|
ESP_LOGW(TAG, "i2c_driver_install failed: %s", esp_err_to_name(err));
|
73
73
|
this->mark_failed();
|
@@ -8,7 +8,15 @@ from esphome.components.esp32.const import (
|
|
8
8
|
VARIANT_ESP32S3,
|
9
9
|
)
|
10
10
|
import esphome.config_validation as cv
|
11
|
-
from esphome.const import
|
11
|
+
from esphome.const import (
|
12
|
+
CONF_BITS_PER_SAMPLE,
|
13
|
+
CONF_CHANNEL,
|
14
|
+
CONF_ID,
|
15
|
+
CONF_SAMPLE_RATE,
|
16
|
+
KEY_CORE,
|
17
|
+
KEY_FRAMEWORK_VERSION,
|
18
|
+
)
|
19
|
+
from esphome.core import CORE
|
12
20
|
from esphome.cpp_generator import MockObjClass
|
13
21
|
import esphome.final_validate as fv
|
14
22
|
|
@@ -31,10 +39,14 @@ CONF_SECONDARY = "secondary"
|
|
31
39
|
|
32
40
|
CONF_USE_APLL = "use_apll"
|
33
41
|
CONF_BITS_PER_CHANNEL = "bits_per_channel"
|
42
|
+
CONF_MCLK_MULTIPLE = "mclk_multiple"
|
34
43
|
CONF_MONO = "mono"
|
35
44
|
CONF_LEFT = "left"
|
36
45
|
CONF_RIGHT = "right"
|
37
46
|
CONF_STEREO = "stereo"
|
47
|
+
CONF_BOTH = "both"
|
48
|
+
|
49
|
+
CONF_USE_LEGACY = "use_legacy"
|
38
50
|
|
39
51
|
i2s_audio_ns = cg.esphome_ns.namespace("i2s_audio")
|
40
52
|
I2SAudioComponent = i2s_audio_ns.class_("I2SAudioComponent", cg.Component)
|
@@ -50,6 +62,12 @@ I2S_MODE_OPTIONS = {
|
|
50
62
|
CONF_SECONDARY: i2s_mode_t.I2S_MODE_SLAVE, # NOLINT
|
51
63
|
}
|
52
64
|
|
65
|
+
i2s_role_t = cg.global_ns.enum("i2s_role_t")
|
66
|
+
I2S_ROLE_OPTIONS = {
|
67
|
+
CONF_PRIMARY: i2s_role_t.I2S_ROLE_MASTER, # NOLINT
|
68
|
+
CONF_SECONDARY: i2s_role_t.I2S_ROLE_SLAVE, # NOLINT
|
69
|
+
}
|
70
|
+
|
53
71
|
# https://github.com/espressif/esp-idf/blob/master/components/soc/{variant}/include/soc/soc_caps.h
|
54
72
|
I2S_PORTS = {
|
55
73
|
VARIANT_ESP32: 2,
|
@@ -60,10 +78,23 @@ I2S_PORTS = {
|
|
60
78
|
|
61
79
|
i2s_channel_fmt_t = cg.global_ns.enum("i2s_channel_fmt_t")
|
62
80
|
I2S_CHANNELS = {
|
63
|
-
CONF_MONO: i2s_channel_fmt_t.I2S_CHANNEL_FMT_ALL_LEFT,
|
64
|
-
CONF_LEFT: i2s_channel_fmt_t.I2S_CHANNEL_FMT_ONLY_LEFT,
|
65
|
-
CONF_RIGHT: i2s_channel_fmt_t.I2S_CHANNEL_FMT_ONLY_RIGHT,
|
66
|
-
CONF_STEREO: i2s_channel_fmt_t.I2S_CHANNEL_FMT_RIGHT_LEFT,
|
81
|
+
CONF_MONO: i2s_channel_fmt_t.I2S_CHANNEL_FMT_ALL_LEFT, # left data to both channels
|
82
|
+
CONF_LEFT: i2s_channel_fmt_t.I2S_CHANNEL_FMT_ONLY_LEFT, # mono data
|
83
|
+
CONF_RIGHT: i2s_channel_fmt_t.I2S_CHANNEL_FMT_ONLY_RIGHT, # mono data
|
84
|
+
CONF_STEREO: i2s_channel_fmt_t.I2S_CHANNEL_FMT_RIGHT_LEFT, # stereo data to both channels
|
85
|
+
}
|
86
|
+
|
87
|
+
i2s_slot_mode_t = cg.global_ns.enum("i2s_slot_mode_t")
|
88
|
+
I2S_SLOT_MODE = {
|
89
|
+
CONF_MONO: i2s_slot_mode_t.I2S_SLOT_MODE_MONO,
|
90
|
+
CONF_STEREO: i2s_slot_mode_t.I2S_SLOT_MODE_STEREO,
|
91
|
+
}
|
92
|
+
|
93
|
+
i2s_std_slot_mask_t = cg.global_ns.enum("i2s_std_slot_mask_t")
|
94
|
+
I2S_STD_SLOT_MASK = {
|
95
|
+
CONF_LEFT: i2s_std_slot_mask_t.I2S_STD_SLOT_LEFT,
|
96
|
+
CONF_RIGHT: i2s_std_slot_mask_t.I2S_STD_SLOT_RIGHT,
|
97
|
+
CONF_BOTH: i2s_std_slot_mask_t.I2S_STD_SLOT_BOTH,
|
67
98
|
}
|
68
99
|
|
69
100
|
i2s_bits_per_sample_t = cg.global_ns.enum("i2s_bits_per_sample_t")
|
@@ -83,9 +114,37 @@ I2S_BITS_PER_CHANNEL = {
|
|
83
114
|
32: i2s_bits_per_chan_t.I2S_BITS_PER_CHAN_32BIT,
|
84
115
|
}
|
85
116
|
|
117
|
+
i2s_slot_bit_width_t = cg.global_ns.enum("i2s_slot_bit_width_t")
|
118
|
+
I2S_SLOT_BIT_WIDTH = {
|
119
|
+
"default": i2s_slot_bit_width_t.I2S_SLOT_BIT_WIDTH_AUTO,
|
120
|
+
8: i2s_slot_bit_width_t.I2S_SLOT_BIT_WIDTH_8BIT,
|
121
|
+
16: i2s_slot_bit_width_t.I2S_SLOT_BIT_WIDTH_16BIT,
|
122
|
+
24: i2s_slot_bit_width_t.I2S_SLOT_BIT_WIDTH_24BIT,
|
123
|
+
32: i2s_slot_bit_width_t.I2S_SLOT_BIT_WIDTH_32BIT,
|
124
|
+
}
|
125
|
+
|
126
|
+
i2s_mclk_multiple_t = cg.global_ns.enum("i2s_mclk_multiple_t")
|
127
|
+
I2S_MCLK_MULTIPLE = {
|
128
|
+
128: i2s_mclk_multiple_t.I2S_MCLK_MULTIPLE_128,
|
129
|
+
256: i2s_mclk_multiple_t.I2S_MCLK_MULTIPLE_256,
|
130
|
+
384: i2s_mclk_multiple_t.I2S_MCLK_MULTIPLE_384,
|
131
|
+
512: i2s_mclk_multiple_t.I2S_MCLK_MULTIPLE_512,
|
132
|
+
}
|
133
|
+
|
86
134
|
_validate_bits = cv.float_with_unit("bits", "bit")
|
87
135
|
|
88
136
|
|
137
|
+
def validate_mclk_divisible_by_3(config):
|
138
|
+
if config[CONF_BITS_PER_SAMPLE] == 24 and config[CONF_MCLK_MULTIPLE] % 3 != 0:
|
139
|
+
raise cv.Invalid(
|
140
|
+
f"{CONF_MCLK_MULTIPLE} must be divisible by 3 when bits per sample is 24"
|
141
|
+
)
|
142
|
+
return config
|
143
|
+
|
144
|
+
|
145
|
+
_use_legacy_driver = None
|
146
|
+
|
147
|
+
|
89
148
|
def i2s_audio_component_schema(
|
90
149
|
class_: MockObjClass,
|
91
150
|
*,
|
@@ -97,43 +156,83 @@ def i2s_audio_component_schema(
|
|
97
156
|
{
|
98
157
|
cv.GenerateID(): cv.declare_id(class_),
|
99
158
|
cv.GenerateID(CONF_I2S_AUDIO_ID): cv.use_id(I2SAudioComponent),
|
100
|
-
cv.Optional(CONF_CHANNEL, default=default_channel): cv.
|
159
|
+
cv.Optional(CONF_CHANNEL, default=default_channel): cv.one_of(
|
160
|
+
*I2S_CHANNELS
|
161
|
+
),
|
101
162
|
cv.Optional(CONF_SAMPLE_RATE, default=default_sample_rate): cv.int_range(
|
102
163
|
min=1
|
103
164
|
),
|
104
165
|
cv.Optional(CONF_BITS_PER_SAMPLE, default=default_bits_per_sample): cv.All(
|
105
|
-
_validate_bits, cv.
|
166
|
+
_validate_bits, cv.one_of(*I2S_BITS_PER_SAMPLE)
|
106
167
|
),
|
107
|
-
cv.Optional(CONF_I2S_MODE, default=CONF_PRIMARY): cv.
|
108
|
-
I2S_MODE_OPTIONS, lower=True
|
168
|
+
cv.Optional(CONF_I2S_MODE, default=CONF_PRIMARY): cv.one_of(
|
169
|
+
*I2S_MODE_OPTIONS, lower=True
|
109
170
|
),
|
110
171
|
cv.Optional(CONF_USE_APLL, default=False): cv.boolean,
|
111
172
|
cv.Optional(CONF_BITS_PER_CHANNEL, default="default"): cv.All(
|
112
173
|
cv.Any(cv.float_with_unit("bits", "bit"), "default"),
|
113
|
-
cv.
|
174
|
+
cv.one_of(*I2S_BITS_PER_CHANNEL),
|
114
175
|
),
|
176
|
+
cv.Optional(CONF_MCLK_MULTIPLE, default=256): cv.one_of(*I2S_MCLK_MULTIPLE),
|
115
177
|
}
|
116
178
|
)
|
117
179
|
|
118
180
|
|
119
181
|
async def register_i2s_audio_component(var, config):
|
120
182
|
await cg.register_parented(var, config[CONF_I2S_AUDIO_ID])
|
121
|
-
|
122
|
-
|
123
|
-
|
183
|
+
if use_legacy():
|
184
|
+
cg.add(var.set_i2s_mode(I2S_MODE_OPTIONS[config[CONF_I2S_MODE]]))
|
185
|
+
cg.add(var.set_channel(I2S_CHANNELS[config[CONF_CHANNEL]]))
|
186
|
+
cg.add(
|
187
|
+
var.set_bits_per_sample(I2S_BITS_PER_SAMPLE[config[CONF_BITS_PER_SAMPLE]])
|
188
|
+
)
|
189
|
+
cg.add(
|
190
|
+
var.set_bits_per_channel(
|
191
|
+
I2S_BITS_PER_CHANNEL[config[CONF_BITS_PER_CHANNEL]]
|
192
|
+
)
|
193
|
+
)
|
194
|
+
else:
|
195
|
+
cg.add(var.set_i2s_role(I2S_ROLE_OPTIONS[config[CONF_I2S_MODE]]))
|
196
|
+
slot_mode = config[CONF_CHANNEL]
|
197
|
+
if slot_mode != CONF_STEREO:
|
198
|
+
slot_mode = CONF_MONO
|
199
|
+
slot_mask = config[CONF_CHANNEL]
|
200
|
+
if slot_mask not in [CONF_LEFT, CONF_RIGHT]:
|
201
|
+
slot_mask = CONF_BOTH
|
202
|
+
cg.add(var.set_slot_mode(I2S_SLOT_MODE[slot_mode]))
|
203
|
+
cg.add(var.set_std_slot_mask(I2S_STD_SLOT_MASK[slot_mask]))
|
204
|
+
cg.add(var.set_slot_bit_width(I2S_SLOT_BIT_WIDTH[config[CONF_BITS_PER_SAMPLE]]))
|
124
205
|
cg.add(var.set_sample_rate(config[CONF_SAMPLE_RATE]))
|
125
|
-
cg.add(var.set_bits_per_sample(config[CONF_BITS_PER_SAMPLE]))
|
126
|
-
cg.add(var.set_bits_per_channel(config[CONF_BITS_PER_CHANNEL]))
|
127
206
|
cg.add(var.set_use_apll(config[CONF_USE_APLL]))
|
207
|
+
cg.add(var.set_mclk_multiple(I2S_MCLK_MULTIPLE[config[CONF_MCLK_MULTIPLE]]))
|
208
|
+
|
209
|
+
|
210
|
+
def validate_use_legacy(value):
|
211
|
+
global _use_legacy_driver # noqa: PLW0603
|
212
|
+
if CONF_USE_LEGACY in value:
|
213
|
+
if (_use_legacy_driver is not None) and (
|
214
|
+
_use_legacy_driver != value[CONF_USE_LEGACY]
|
215
|
+
):
|
216
|
+
raise cv.Invalid(
|
217
|
+
f"All i2s_audio components must set {CONF_USE_LEGACY} to the same value."
|
218
|
+
)
|
219
|
+
if (not value[CONF_USE_LEGACY]) and (CORE.using_arduino):
|
220
|
+
raise cv.Invalid("Arduino supports only the legacy i2s driver.")
|
221
|
+
_use_legacy_driver = value[CONF_USE_LEGACY]
|
222
|
+
return value
|
128
223
|
|
129
224
|
|
130
|
-
CONFIG_SCHEMA = cv.
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
225
|
+
CONFIG_SCHEMA = cv.All(
|
226
|
+
cv.Schema(
|
227
|
+
{
|
228
|
+
cv.GenerateID(): cv.declare_id(I2SAudioComponent),
|
229
|
+
cv.Required(CONF_I2S_LRCLK_PIN): pins.internal_gpio_output_pin_number,
|
230
|
+
cv.Optional(CONF_I2S_BCLK_PIN): pins.internal_gpio_output_pin_number,
|
231
|
+
cv.Optional(CONF_I2S_MCLK_PIN): pins.internal_gpio_output_pin_number,
|
232
|
+
cv.Optional(CONF_USE_LEGACY): cv.boolean,
|
233
|
+
},
|
234
|
+
),
|
235
|
+
validate_use_legacy,
|
137
236
|
)
|
138
237
|
|
139
238
|
|
@@ -148,12 +247,22 @@ def _final_validate(_):
|
|
148
247
|
)
|
149
248
|
|
150
249
|
|
250
|
+
def use_legacy():
|
251
|
+
framework_version = CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION]
|
252
|
+
if CORE.using_esp_idf and framework_version >= cv.Version(5, 0, 0):
|
253
|
+
if not _use_legacy_driver:
|
254
|
+
return False
|
255
|
+
return True
|
256
|
+
|
257
|
+
|
151
258
|
FINAL_VALIDATE_SCHEMA = _final_validate
|
152
259
|
|
153
260
|
|
154
261
|
async def to_code(config):
|
155
262
|
var = cg.new_Pvariable(config[CONF_ID])
|
156
263
|
await cg.register_component(var, config)
|
264
|
+
if use_legacy():
|
265
|
+
cg.add_define("USE_I2S_LEGACY")
|
157
266
|
|
158
267
|
cg.add(var.set_lrclk_pin(config[CONF_I2S_LRCLK_PIN]))
|
159
268
|
if CONF_I2S_BCLK_PIN in config:
|
@@ -2,9 +2,14 @@
|
|
2
2
|
|
3
3
|
#ifdef USE_ESP32
|
4
4
|
|
5
|
-
#include <driver/i2s.h>
|
6
5
|
#include "esphome/core/component.h"
|
7
6
|
#include "esphome/core/helpers.h"
|
7
|
+
#include "esphome/core/defines.h"
|
8
|
+
#ifdef USE_I2S_LEGACY
|
9
|
+
#include <driver/i2s.h>
|
10
|
+
#else
|
11
|
+
#include <driver/i2s_std.h>
|
12
|
+
#endif
|
8
13
|
|
9
14
|
namespace esphome {
|
10
15
|
namespace i2s_audio {
|
@@ -13,20 +18,36 @@ class I2SAudioComponent;
|
|
13
18
|
|
14
19
|
class I2SAudioBase : public Parented<I2SAudioComponent> {
|
15
20
|
public:
|
21
|
+
#ifdef USE_I2S_LEGACY
|
16
22
|
void set_i2s_mode(i2s_mode_t mode) { this->i2s_mode_ = mode; }
|
17
23
|
void set_channel(i2s_channel_fmt_t channel) { this->channel_ = channel; }
|
18
|
-
void set_sample_rate(uint32_t sample_rate) { this->sample_rate_ = sample_rate; }
|
19
24
|
void set_bits_per_sample(i2s_bits_per_sample_t bits_per_sample) { this->bits_per_sample_ = bits_per_sample; }
|
20
25
|
void set_bits_per_channel(i2s_bits_per_chan_t bits_per_channel) { this->bits_per_channel_ = bits_per_channel; }
|
26
|
+
#else
|
27
|
+
void set_i2s_role(i2s_role_t role) { this->i2s_role_ = role; }
|
28
|
+
void set_slot_mode(i2s_slot_mode_t slot_mode) { this->slot_mode_ = slot_mode; }
|
29
|
+
void set_std_slot_mask(i2s_std_slot_mask_t std_slot_mask) { this->std_slot_mask_ = std_slot_mask; }
|
30
|
+
void set_slot_bit_width(i2s_slot_bit_width_t slot_bit_width) { this->slot_bit_width_ = slot_bit_width; }
|
31
|
+
#endif
|
32
|
+
void set_sample_rate(uint32_t sample_rate) { this->sample_rate_ = sample_rate; }
|
21
33
|
void set_use_apll(uint32_t use_apll) { this->use_apll_ = use_apll; }
|
34
|
+
void set_mclk_multiple(i2s_mclk_multiple_t mclk_multiple) { this->mclk_multiple_ = mclk_multiple; }
|
22
35
|
|
23
36
|
protected:
|
37
|
+
#ifdef USE_I2S_LEGACY
|
24
38
|
i2s_mode_t i2s_mode_{};
|
25
39
|
i2s_channel_fmt_t channel_;
|
26
|
-
uint32_t sample_rate_;
|
27
40
|
i2s_bits_per_sample_t bits_per_sample_;
|
28
41
|
i2s_bits_per_chan_t bits_per_channel_;
|
42
|
+
#else
|
43
|
+
i2s_role_t i2s_role_{};
|
44
|
+
i2s_slot_mode_t slot_mode_;
|
45
|
+
i2s_std_slot_mask_t std_slot_mask_;
|
46
|
+
i2s_slot_bit_width_t slot_bit_width_;
|
47
|
+
#endif
|
48
|
+
uint32_t sample_rate_;
|
29
49
|
bool use_apll_;
|
50
|
+
i2s_mclk_multiple_t mclk_multiple_;
|
30
51
|
};
|
31
52
|
|
32
53
|
class I2SAudioIn : public I2SAudioBase {};
|
@@ -37,6 +58,7 @@ class I2SAudioComponent : public Component {
|
|
37
58
|
public:
|
38
59
|
void setup() override;
|
39
60
|
|
61
|
+
#ifdef USE_I2S_LEGACY
|
40
62
|
i2s_pin_config_t get_pin_config() const {
|
41
63
|
return {
|
42
64
|
.mck_io_num = this->mclk_pin_,
|
@@ -46,6 +68,20 @@ class I2SAudioComponent : public Component {
|
|
46
68
|
.data_in_num = I2S_PIN_NO_CHANGE,
|
47
69
|
};
|
48
70
|
}
|
71
|
+
#else
|
72
|
+
i2s_std_gpio_config_t get_pin_config() const {
|
73
|
+
return {.mclk = (gpio_num_t) this->mclk_pin_,
|
74
|
+
.bclk = (gpio_num_t) this->bclk_pin_,
|
75
|
+
.ws = (gpio_num_t) this->lrclk_pin_,
|
76
|
+
.dout = I2S_GPIO_UNUSED, // add local ports
|
77
|
+
.din = I2S_GPIO_UNUSED,
|
78
|
+
.invert_flags = {
|
79
|
+
.mclk_inv = false,
|
80
|
+
.bclk_inv = false,
|
81
|
+
.ws_inv = false,
|
82
|
+
}};
|
83
|
+
}
|
84
|
+
#endif
|
49
85
|
|
50
86
|
void set_mclk_pin(int pin) { this->mclk_pin_ = pin; }
|
51
87
|
void set_bclk_pin(int pin) { this->bclk_pin_ = pin; }
|
@@ -62,9 +98,13 @@ class I2SAudioComponent : public Component {
|
|
62
98
|
|
63
99
|
I2SAudioIn *audio_in_{nullptr};
|
64
100
|
I2SAudioOut *audio_out_{nullptr};
|
65
|
-
|
101
|
+
#ifdef USE_I2S_LEGACY
|
66
102
|
int mclk_pin_{I2S_PIN_NO_CHANGE};
|
67
103
|
int bclk_pin_{I2S_PIN_NO_CHANGE};
|
104
|
+
#else
|
105
|
+
int mclk_pin_{I2S_GPIO_UNUSED};
|
106
|
+
int bclk_pin_{I2S_GPIO_UNUSED};
|
107
|
+
#endif
|
68
108
|
int lrclk_pin_;
|
69
109
|
i2s_port_t port_{};
|
70
110
|
};
|
@@ -2,7 +2,7 @@ from esphome import pins
|
|
2
2
|
import esphome.codegen as cg
|
3
3
|
from esphome.components import esp32, media_player
|
4
4
|
import esphome.config_validation as cv
|
5
|
-
from esphome.const import
|
5
|
+
from esphome.const import CONF_MODE
|
6
6
|
|
7
7
|
from .. import (
|
8
8
|
CONF_I2S_AUDIO_ID,
|
@@ -14,6 +14,7 @@ from .. import (
|
|
14
14
|
I2SAudioComponent,
|
15
15
|
I2SAudioOut,
|
16
16
|
i2s_audio_ns,
|
17
|
+
use_legacy,
|
17
18
|
)
|
18
19
|
|
19
20
|
CODEOWNERS = ["@jesserockz"]
|
@@ -56,16 +57,17 @@ def validate_esp32_variant(config):
|
|
56
57
|
CONFIG_SCHEMA = cv.All(
|
57
58
|
cv.typed_schema(
|
58
59
|
{
|
59
|
-
"internal": media_player.
|
60
|
+
"internal": media_player.media_player_schema(I2SAudioMediaPlayer)
|
61
|
+
.extend(
|
60
62
|
{
|
61
|
-
cv.GenerateID(): cv.declare_id(I2SAudioMediaPlayer),
|
62
63
|
cv.GenerateID(CONF_I2S_AUDIO_ID): cv.use_id(I2SAudioComponent),
|
63
64
|
cv.Required(CONF_MODE): cv.enum(INTERNAL_DAC_OPTIONS, lower=True),
|
64
65
|
}
|
65
|
-
)
|
66
|
-
|
66
|
+
)
|
67
|
+
.extend(cv.COMPONENT_SCHEMA),
|
68
|
+
"external": media_player.media_player_schema(I2SAudioMediaPlayer)
|
69
|
+
.extend(
|
67
70
|
{
|
68
|
-
cv.GenerateID(): cv.declare_id(I2SAudioMediaPlayer),
|
69
71
|
cv.GenerateID(CONF_I2S_AUDIO_ID): cv.use_id(I2SAudioComponent),
|
70
72
|
cv.Required(
|
71
73
|
CONF_I2S_DOUT_PIN
|
@@ -78,7 +80,8 @@ CONFIG_SCHEMA = cv.All(
|
|
78
80
|
*I2C_COMM_FMT_OPTIONS, lower=True
|
79
81
|
),
|
80
82
|
}
|
81
|
-
)
|
83
|
+
)
|
84
|
+
.extend(cv.COMPONENT_SCHEMA),
|
82
85
|
},
|
83
86
|
key=CONF_DAC_TYPE,
|
84
87
|
),
|
@@ -87,10 +90,17 @@ CONFIG_SCHEMA = cv.All(
|
|
87
90
|
)
|
88
91
|
|
89
92
|
|
93
|
+
def _final_validate(_):
|
94
|
+
if not use_legacy():
|
95
|
+
raise cv.Invalid("I2S media player is only compatible with legacy i2s driver.")
|
96
|
+
|
97
|
+
|
98
|
+
FINAL_VALIDATE_SCHEMA = _final_validate
|
99
|
+
|
100
|
+
|
90
101
|
async def to_code(config):
|
91
|
-
var =
|
102
|
+
var = await media_player.new_media_player(config)
|
92
103
|
await cg.register_component(var, config)
|
93
|
-
await media_player.register_media_player(var, config)
|
94
104
|
|
95
105
|
await cg.register_parented(var, config[CONF_I2S_AUDIO_ID])
|
96
106
|
|
@@ -1,17 +1,28 @@
|
|
1
1
|
from esphome import pins
|
2
2
|
import esphome.codegen as cg
|
3
|
-
from esphome.components import esp32, microphone
|
3
|
+
from esphome.components import audio, esp32, microphone
|
4
4
|
from esphome.components.adc import ESP32_VARIANT_ADC1_PIN_TO_CHANNEL, validate_adc_pin
|
5
5
|
import esphome.config_validation as cv
|
6
|
-
from esphome.const import
|
6
|
+
from esphome.const import (
|
7
|
+
CONF_BITS_PER_SAMPLE,
|
8
|
+
CONF_CHANNEL,
|
9
|
+
CONF_ID,
|
10
|
+
CONF_NUM_CHANNELS,
|
11
|
+
CONF_NUMBER,
|
12
|
+
CONF_SAMPLE_RATE,
|
13
|
+
)
|
7
14
|
|
8
15
|
from .. import (
|
9
16
|
CONF_I2S_DIN_PIN,
|
17
|
+
CONF_LEFT,
|
18
|
+
CONF_MONO,
|
10
19
|
CONF_RIGHT,
|
11
20
|
I2SAudioIn,
|
12
21
|
i2s_audio_component_schema,
|
13
22
|
i2s_audio_ns,
|
14
23
|
register_i2s_audio_component,
|
24
|
+
use_legacy,
|
25
|
+
validate_mclk_divisible_by_3,
|
15
26
|
)
|
16
27
|
|
17
28
|
CODEOWNERS = ["@jesserockz"]
|
@@ -19,6 +30,7 @@ DEPENDENCIES = ["i2s_audio"]
|
|
19
30
|
|
20
31
|
CONF_ADC_PIN = "adc_pin"
|
21
32
|
CONF_ADC_TYPE = "adc_type"
|
33
|
+
CONF_CORRECT_DC_OFFSET = "correct_dc_offset"
|
22
34
|
CONF_PDM = "pdm"
|
23
35
|
|
24
36
|
I2SAudioMicrophone = i2s_audio_ns.class_(
|
@@ -29,7 +41,7 @@ INTERNAL_ADC_VARIANTS = [esp32.const.VARIANT_ESP32]
|
|
29
41
|
PDM_VARIANTS = [esp32.const.VARIANT_ESP32, esp32.const.VARIANT_ESP32S3]
|
30
42
|
|
31
43
|
|
32
|
-
def
|
44
|
+
def _validate_esp32_variant(config):
|
33
45
|
variant = esp32.get_esp32_variant()
|
34
46
|
if config[CONF_ADC_TYPE] == "external":
|
35
47
|
if config[CONF_PDM]:
|
@@ -43,16 +55,47 @@ def validate_esp32_variant(config):
|
|
43
55
|
raise NotImplementedError
|
44
56
|
|
45
57
|
|
58
|
+
def _validate_channel(config):
|
59
|
+
if config[CONF_CHANNEL] == CONF_MONO:
|
60
|
+
raise cv.Invalid(f"I2S microphone does not support {CONF_MONO}.")
|
61
|
+
return config
|
62
|
+
|
63
|
+
|
64
|
+
def _set_num_channels_from_config(config):
|
65
|
+
if config[CONF_CHANNEL] in (CONF_LEFT, CONF_RIGHT):
|
66
|
+
config[CONF_NUM_CHANNELS] = 1
|
67
|
+
else:
|
68
|
+
config[CONF_NUM_CHANNELS] = 2
|
69
|
+
|
70
|
+
return config
|
71
|
+
|
72
|
+
|
73
|
+
def _set_stream_limits(config):
|
74
|
+
audio.set_stream_limits(
|
75
|
+
min_bits_per_sample=config.get(CONF_BITS_PER_SAMPLE),
|
76
|
+
max_bits_per_sample=config.get(CONF_BITS_PER_SAMPLE),
|
77
|
+
min_channels=config.get(CONF_NUM_CHANNELS),
|
78
|
+
max_channels=config.get(CONF_NUM_CHANNELS),
|
79
|
+
min_sample_rate=config.get(CONF_SAMPLE_RATE),
|
80
|
+
max_sample_rate=config.get(CONF_SAMPLE_RATE),
|
81
|
+
)(config)
|
82
|
+
|
83
|
+
return config
|
84
|
+
|
85
|
+
|
46
86
|
BASE_SCHEMA = microphone.MICROPHONE_SCHEMA.extend(
|
47
87
|
i2s_audio_component_schema(
|
48
88
|
I2SAudioMicrophone,
|
49
89
|
default_sample_rate=16000,
|
50
90
|
default_channel=CONF_RIGHT,
|
51
91
|
default_bits_per_sample="32bit",
|
92
|
+
).extend(
|
93
|
+
{
|
94
|
+
cv.Optional(CONF_CORRECT_DC_OFFSET, default=False): cv.boolean,
|
95
|
+
}
|
52
96
|
)
|
53
97
|
).extend(cv.COMPONENT_SCHEMA)
|
54
98
|
|
55
|
-
|
56
99
|
CONFIG_SCHEMA = cv.All(
|
57
100
|
cv.typed_schema(
|
58
101
|
{
|
@@ -70,10 +113,23 @@ CONFIG_SCHEMA = cv.All(
|
|
70
113
|
},
|
71
114
|
key=CONF_ADC_TYPE,
|
72
115
|
),
|
73
|
-
|
116
|
+
_validate_esp32_variant,
|
117
|
+
_validate_channel,
|
118
|
+
_set_num_channels_from_config,
|
119
|
+
_set_stream_limits,
|
120
|
+
validate_mclk_divisible_by_3,
|
74
121
|
)
|
75
122
|
|
76
123
|
|
124
|
+
def _final_validate(config):
|
125
|
+
if not use_legacy():
|
126
|
+
if config[CONF_ADC_TYPE] == "internal":
|
127
|
+
raise cv.Invalid("Internal ADC is only compatible with legacy i2s driver.")
|
128
|
+
|
129
|
+
|
130
|
+
FINAL_VALIDATE_SCHEMA = _final_validate
|
131
|
+
|
132
|
+
|
77
133
|
async def to_code(config):
|
78
134
|
var = cg.new_Pvariable(config[CONF_ID])
|
79
135
|
await cg.register_component(var, config)
|
@@ -88,3 +144,5 @@ async def to_code(config):
|
|
88
144
|
else:
|
89
145
|
cg.add(var.set_din_pin(config[CONF_I2S_DIN_PIN]))
|
90
146
|
cg.add(var.set_pdm(config[CONF_PDM]))
|
147
|
+
|
148
|
+
cg.add(var.set_correct_dc_offset(config[CONF_CORRECT_DC_OFFSET]))
|