esphome 2025.4.2__py3-none-any.whl → 2025.5.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 +16 -14
- 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 +416 -662
- esphome/components/api/api_connection.h +256 -57
- esphome/components/api/api_frame_helper.cpp +232 -177
- esphome/components/api/api_frame_helper.h +61 -8
- 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 +86 -17
- esphome/components/as7341/as7341.h +1 -1
- esphome/components/at581x/at581x.h +4 -4
- 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/bedjet_hub.cpp +1 -0
- 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/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 +136 -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/ccs811/sensor.py +9 -6
- 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/cse7766/cse7766.cpp +2 -1
- 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/current_based/current_based_cover.cpp +2 -1
- 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/daly_bms/daly_bms.cpp +2 -1
- esphome/components/debug/debug_component.cpp +6 -1
- esphome/components/debug/debug_component.h +8 -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/dps310/sensor.py +6 -6
- esphome/components/ee895/sensor.py +9 -9
- esphome/components/emmeti/climate.py +2 -9
- esphome/components/endstop/cover.py +17 -16
- esphome/components/endstop/endstop_cover.cpp +2 -1
- esphome/components/ens160_base/__init__.py +12 -9
- 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 -0
- esphome/components/esp32_ble/ble.h +5 -3
- esphome/components/esp32_ble/ble_advertising.cpp +2 -1
- 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_camera/__init__.py +1 -1
- esphome/components/esp32_camera/esp32_camera.cpp +2 -10
- esphome/components/esp32_camera/esp32_camera.h +1 -1
- esphome/components/esp32_can/esp32_can.cpp +1 -1
- esphome/components/esp32_improv/esp32_improv_component.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/esp32_touch/esp32_touch.cpp +1 -1
- esphome/components/esp8266/gpio.cpp +69 -8
- esphome/components/ethernet/ethernet_component.cpp +1 -1
- 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/feedback/feedback_cover.cpp +2 -1
- esphome/components/fujitsu_general/climate.py +2 -9
- esphome/components/gcja5/gcja5.cpp +2 -1
- 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 +47 -17
- esphome/components/gps/gps.cpp +42 -23
- esphome/components/gps/gps.h +17 -13
- 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/growatt_solar/growatt_solar.cpp +2 -1
- 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/hm3301/hm3301.h +1 -1
- esphome/components/hte501/sensor.py +6 -6
- 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/hyt271/sensor.py +6 -6
- 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/kuntze/kuntze.cpp +2 -1
- 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 +22 -0
- esphome/components/logger/logger.cpp +154 -103
- esphome/components/logger/logger.h +211 -36
- 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/lvgl_esphome.cpp +5 -1
- esphome/components/lvgl/text/__init__.py +1 -2
- esphome/components/mapping/__init__.py +134 -0
- esphome/components/matrix_keypad/matrix_keypad.cpp +2 -1
- esphome/components/max7219digit/max7219digit.cpp +28 -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 +33 -1
- esphome/components/mhz19/sensor.py +11 -7
- 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/modbus/modbus.cpp +2 -1
- esphome/components/mqtt/__init__.py +1 -1
- esphome/components/mqtt/mqtt_client.cpp +6 -2
- 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/ms5611/sensor.py +6 -6
- esphome/components/ms8607/sensor.py +3 -3
- 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 +195 -230
- 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/pzem004t/pzem004t.cpp +2 -1
- 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/rf_bridge/rf_bridge.cpp +2 -1
- esphome/components/scd30/sensor.py +2 -3
- esphome/components/scd4x/sensor.py +4 -5
- esphome/components/sdp3x/sensor.py +2 -1
- esphome/components/sds011/sds011.cpp +2 -1
- esphome/components/select/__init__.py +19 -20
- esphome/components/sen5x/sen5x.cpp +55 -36
- esphome/components/sen5x/sensor.py +1 -1
- esphome/components/senseair/sensor.py +3 -3
- esphome/components/sensor/__init__.py +158 -14
- esphome/components/sensor/filter.cpp +23 -0
- esphome/components/sensor/filter.h +22 -0
- esphome/components/sgp30/sensor.py +14 -16
- esphome/components/sgp4x/sensor.py +1 -1
- esphome/components/sht4x/sht4x.cpp +43 -22
- esphome/components/sht4x/sht4x.h +1 -1
- esphome/components/shtcx/sensor.py +6 -6
- esphome/components/slow_pwm/slow_pwm_output.cpp +2 -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/sprinkler/sprinkler.cpp +6 -5
- 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/t6615/sensor.py +3 -3
- esphome/components/t6615/t6615.cpp +2 -1
- 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/time_based/time_based_cover.cpp +2 -1
- 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/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/uart/switch/uart_switch.cpp +2 -1
- 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/uponor_smatrix/climate/uponor_smatrix_climate.cpp +2 -1
- esphome/components/uponor_smatrix/uponor_smatrix.cpp +2 -1
- 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/weikai/weikai.cpp +0 -52
- 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.py +13 -13
- esphome/config_validation.py +38 -58
- esphome/const.py +15 -1
- esphome/core/__init__.py +2 -0
- esphome/core/application.cpp +27 -10
- esphome/core/application.h +9 -1
- esphome/core/automation.h +4 -3
- esphome/core/component.cpp +28 -7
- esphome/core/component.h +10 -1
- esphome/core/defines.h +23 -17
- esphome/core/doxygen.h +13 -0
- esphome/core/macros.h +4 -0
- esphome/core/scheduler.cpp +7 -1
- esphome/cpp_generator.py +6 -2
- esphome/dashboard/web_server.py +3 -3
- esphome/helpers.py +39 -0
- esphome/loader.py +4 -0
- esphome/log.py +15 -19
- esphome/mqtt.py +23 -10
- esphome/platformio_api.py +1 -1
- esphome/schema_extractors.py +0 -1
- esphome/voluptuous_schema.py +3 -1
- esphome/vscode.py +15 -0
- esphome/wizard.py +47 -37
- esphome/zeroconf.py +7 -3
- {esphome-2025.4.2.dist-info → esphome-2025.5.0.dist-info}/METADATA +10 -11
- {esphome-2025.4.2.dist-info → esphome-2025.5.0.dist-info}/RECORD +444 -383
- {esphome-2025.4.2.dist-info → esphome-2025.5.0.dist-info}/WHEEL +1 -1
- {esphome-2025.4.2.dist-info → esphome-2025.5.0.dist-info}/entry_points.txt +0 -0
- {esphome-2025.4.2.dist-info → esphome-2025.5.0.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.4.2.dist-info → esphome-2025.5.0.dist-info}/top_level.txt +0 -0
@@ -26,13 +26,13 @@ CONFIG_SCHEMA = (
|
|
26
26
|
cv.Schema(
|
27
27
|
{
|
28
28
|
cv.GenerateID(): cv.declare_id(SHTCXComponent),
|
29
|
-
cv.
|
29
|
+
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
|
30
30
|
unit_of_measurement=UNIT_CELSIUS,
|
31
31
|
accuracy_decimals=1,
|
32
32
|
device_class=DEVICE_CLASS_TEMPERATURE,
|
33
33
|
state_class=STATE_CLASS_MEASUREMENT,
|
34
34
|
),
|
35
|
-
cv.
|
35
|
+
cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(
|
36
36
|
unit_of_measurement=UNIT_PERCENT,
|
37
37
|
accuracy_decimals=1,
|
38
38
|
device_class=DEVICE_CLASS_HUMIDITY,
|
@@ -50,10 +50,10 @@ async def to_code(config):
|
|
50
50
|
await cg.register_component(var, config)
|
51
51
|
await i2c.register_i2c_device(var, config)
|
52
52
|
|
53
|
-
if
|
54
|
-
sens = await sensor.new_sensor(
|
53
|
+
if temperature := config.get(CONF_TEMPERATURE):
|
54
|
+
sens = await sensor.new_sensor(temperature)
|
55
55
|
cg.add(var.set_temperature_sensor(sens))
|
56
56
|
|
57
|
-
if
|
58
|
-
sens = await sensor.new_sensor(
|
57
|
+
if humidity := config.get(CONF_HUMIDITY):
|
58
|
+
sens = await sensor.new_sensor(humidity)
|
59
59
|
cg.add(var.set_humidity_sensor(sens))
|
@@ -1,5 +1,6 @@
|
|
1
1
|
#include "slow_pwm_output.h"
|
2
2
|
#include "esphome/core/log.h"
|
3
|
+
#include "esphome/core/application.h"
|
3
4
|
|
4
5
|
namespace esphome {
|
5
6
|
namespace slow_pwm {
|
@@ -39,7 +40,7 @@ void SlowPWMOutput::set_output_state_(bool new_state) {
|
|
39
40
|
}
|
40
41
|
|
41
42
|
void SlowPWMOutput::loop() {
|
42
|
-
uint32_t now =
|
43
|
+
uint32_t now = App.get_loop_component_start_time();
|
43
44
|
float scaled_state = this->state_ * this->period_;
|
44
45
|
|
45
46
|
if (now - this->period_start_time_ >= this->period_) {
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import esphome.codegen as cg
|
2
2
|
from esphome.components import text_sensor
|
3
3
|
import esphome.config_validation as cv
|
4
|
-
from esphome.const import CONF_FORMAT
|
4
|
+
from esphome.const import CONF_FORMAT
|
5
5
|
|
6
6
|
from .. import CONF_OBIS_CODE, CONF_SERVER_ID, CONF_SML_ID, Sml, obis_code, sml_ns
|
7
7
|
|
@@ -19,9 +19,8 @@ SML_TYPES = {
|
|
19
19
|
|
20
20
|
SmlTextSensor = sml_ns.class_("SmlTextSensor", text_sensor.TextSensor, cg.Component)
|
21
21
|
|
22
|
-
CONFIG_SCHEMA = text_sensor.
|
22
|
+
CONFIG_SCHEMA = text_sensor.text_sensor_schema(SmlTextSensor).extend(
|
23
23
|
{
|
24
|
-
cv.GenerateID(): cv.declare_id(SmlTextSensor),
|
25
24
|
cv.GenerateID(CONF_SML_ID): cv.use_id(Sml),
|
26
25
|
cv.Required(CONF_OBIS_CODE): obis_code,
|
27
26
|
cv.Optional(CONF_SERVER_ID, default=""): cv.string,
|
@@ -31,13 +30,12 @@ CONFIG_SCHEMA = text_sensor.TEXT_SENSOR_SCHEMA.extend(
|
|
31
30
|
|
32
31
|
|
33
32
|
async def to_code(config):
|
34
|
-
var =
|
35
|
-
config
|
33
|
+
var = await text_sensor.new_text_sensor(
|
34
|
+
config,
|
36
35
|
config[CONF_SERVER_ID],
|
37
36
|
config[CONF_OBIS_CODE],
|
38
37
|
config[CONF_FORMAT],
|
39
38
|
)
|
40
39
|
await cg.register_component(var, config)
|
41
|
-
await text_sensor.register_text_sensor(var, config)
|
42
40
|
sml = await cg.get_variable(config[CONF_SML_ID])
|
43
41
|
cg.add(sml.register_sml_listener(var))
|
File without changes
|
@@ -0,0 +1,97 @@
|
|
1
|
+
from esphome import automation
|
2
|
+
import esphome.codegen as cg
|
3
|
+
from esphome.components import microphone, sensor
|
4
|
+
import esphome.config_validation as cv
|
5
|
+
from esphome.const import (
|
6
|
+
CONF_ID,
|
7
|
+
CONF_MEASUREMENT_DURATION,
|
8
|
+
CONF_MICROPHONE,
|
9
|
+
DEVICE_CLASS_SOUND_PRESSURE,
|
10
|
+
PLATFORM_ESP32,
|
11
|
+
STATE_CLASS_MEASUREMENT,
|
12
|
+
UNIT_DECIBEL,
|
13
|
+
)
|
14
|
+
|
15
|
+
AUTOLOAD = ["audio"]
|
16
|
+
CODEOWNERS = ["@kahrendt"]
|
17
|
+
DEPENDENCIES = ["microphone"]
|
18
|
+
|
19
|
+
|
20
|
+
CONF_PASSIVE = "passive"
|
21
|
+
CONF_PEAK = "peak"
|
22
|
+
CONF_RMS = "rms"
|
23
|
+
|
24
|
+
sound_level_ns = cg.esphome_ns.namespace("sound_level")
|
25
|
+
SoundLevelComponent = sound_level_ns.class_("SoundLevelComponent", cg.Component)
|
26
|
+
|
27
|
+
StartAction = sound_level_ns.class_("StartAction", automation.Action)
|
28
|
+
StopAction = sound_level_ns.class_("StopAction", automation.Action)
|
29
|
+
|
30
|
+
CONFIG_SCHEMA = cv.All(
|
31
|
+
cv.Schema(
|
32
|
+
{
|
33
|
+
cv.GenerateID(): cv.declare_id(SoundLevelComponent),
|
34
|
+
cv.Optional(CONF_MEASUREMENT_DURATION, default="1000ms"): cv.All(
|
35
|
+
cv.positive_time_period_milliseconds,
|
36
|
+
cv.Range(
|
37
|
+
min=cv.TimePeriod(milliseconds=50),
|
38
|
+
max=cv.TimePeriod(seconds=60),
|
39
|
+
),
|
40
|
+
),
|
41
|
+
cv.Optional(
|
42
|
+
CONF_MICROPHONE, default={}
|
43
|
+
): microphone.microphone_source_schema(
|
44
|
+
min_bits_per_sample=16,
|
45
|
+
max_bits_per_sample=16,
|
46
|
+
),
|
47
|
+
cv.Required(CONF_PASSIVE): cv.boolean,
|
48
|
+
cv.Optional(CONF_PEAK): sensor.sensor_schema(
|
49
|
+
unit_of_measurement=UNIT_DECIBEL,
|
50
|
+
accuracy_decimals=1,
|
51
|
+
device_class=DEVICE_CLASS_SOUND_PRESSURE,
|
52
|
+
state_class=STATE_CLASS_MEASUREMENT,
|
53
|
+
),
|
54
|
+
cv.Optional(CONF_RMS): sensor.sensor_schema(
|
55
|
+
unit_of_measurement=UNIT_DECIBEL,
|
56
|
+
accuracy_decimals=1,
|
57
|
+
device_class=DEVICE_CLASS_SOUND_PRESSURE,
|
58
|
+
state_class=STATE_CLASS_MEASUREMENT,
|
59
|
+
),
|
60
|
+
}
|
61
|
+
).extend(cv.COMPONENT_SCHEMA),
|
62
|
+
cv.only_on([PLATFORM_ESP32]),
|
63
|
+
)
|
64
|
+
|
65
|
+
|
66
|
+
async def to_code(config):
|
67
|
+
var = cg.new_Pvariable(config[CONF_ID])
|
68
|
+
await cg.register_component(var, config)
|
69
|
+
|
70
|
+
mic_source = await microphone.microphone_source_to_code(
|
71
|
+
config[CONF_MICROPHONE], passive=config[CONF_PASSIVE]
|
72
|
+
)
|
73
|
+
cg.add(var.set_microphone_source(mic_source))
|
74
|
+
|
75
|
+
cg.add(var.set_measurement_duration(config[CONF_MEASUREMENT_DURATION]))
|
76
|
+
|
77
|
+
if peak_config := config.get(CONF_PEAK):
|
78
|
+
sens = await sensor.new_sensor(peak_config)
|
79
|
+
cg.add(var.set_peak_sensor(sens))
|
80
|
+
if rms_config := config.get(CONF_RMS):
|
81
|
+
sens = await sensor.new_sensor(rms_config)
|
82
|
+
cg.add(var.set_rms_sensor(sens))
|
83
|
+
|
84
|
+
|
85
|
+
SOUND_LEVEL_ACTION_SCHEMA = automation.maybe_simple_id(
|
86
|
+
{
|
87
|
+
cv.GenerateID(): cv.use_id(SoundLevelComponent),
|
88
|
+
}
|
89
|
+
)
|
90
|
+
|
91
|
+
|
92
|
+
@automation.register_action("sound_level.start", StartAction, SOUND_LEVEL_ACTION_SCHEMA)
|
93
|
+
@automation.register_action("sound_level.stop", StopAction, SOUND_LEVEL_ACTION_SCHEMA)
|
94
|
+
async def sound_level_action_to_code(config, action_id, template_arg, args):
|
95
|
+
var = cg.new_Pvariable(action_id, template_arg)
|
96
|
+
await cg.register_parented(var, config[CONF_ID])
|
97
|
+
return var
|
@@ -0,0 +1,194 @@
|
|
1
|
+
#include "sound_level.h"
|
2
|
+
|
3
|
+
#ifdef USE_ESP32
|
4
|
+
|
5
|
+
#include "esphome/core/log.h"
|
6
|
+
|
7
|
+
#include <cmath>
|
8
|
+
#include <cstdint>
|
9
|
+
|
10
|
+
namespace esphome {
|
11
|
+
namespace sound_level {
|
12
|
+
|
13
|
+
static const char *const TAG = "sound_level";
|
14
|
+
|
15
|
+
static const uint32_t AUDIO_BUFFER_DURATION_MS = 30;
|
16
|
+
static const uint32_t RING_BUFFER_DURATION_MS = 120;
|
17
|
+
|
18
|
+
// Square INT16_MIN since INT16_MIN^2 > INT16_MAX^2
|
19
|
+
static const double MAX_SAMPLE_SQUARED_DENOMINATOR = INT16_MIN * INT16_MIN;
|
20
|
+
|
21
|
+
void SoundLevelComponent::dump_config() {
|
22
|
+
ESP_LOGCONFIG(TAG, "Sound Level Component:");
|
23
|
+
ESP_LOGCONFIG(TAG, " Measurement Duration: %" PRIu32 " ms", measurement_duration_ms_);
|
24
|
+
LOG_SENSOR(" ", "Peak:", this->peak_sensor_);
|
25
|
+
|
26
|
+
LOG_SENSOR(" ", "RMS:", this->rms_sensor_);
|
27
|
+
}
|
28
|
+
|
29
|
+
void SoundLevelComponent::setup() {
|
30
|
+
this->microphone_source_->add_data_callback([this](const std::vector<uint8_t> &data) {
|
31
|
+
std::shared_ptr<RingBuffer> temp_ring_buffer = this->ring_buffer_.lock();
|
32
|
+
if (this->ring_buffer_.use_count() == 2) {
|
33
|
+
// ``audio_buffer_`` and ``temp_ring_buffer`` share ownership of a ring buffer, so its safe/useful to write
|
34
|
+
temp_ring_buffer->write((void *) data.data(), data.size());
|
35
|
+
}
|
36
|
+
});
|
37
|
+
|
38
|
+
if (!this->microphone_source_->is_passive()) {
|
39
|
+
// Automatically start the microphone if not in passive mode
|
40
|
+
this->microphone_source_->start();
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
void SoundLevelComponent::loop() {
|
45
|
+
if ((this->peak_sensor_ == nullptr) && (this->rms_sensor_ == nullptr)) {
|
46
|
+
// No sensors configured, nothing to do
|
47
|
+
return;
|
48
|
+
}
|
49
|
+
|
50
|
+
if (this->microphone_source_->is_running() && !this->status_has_error()) {
|
51
|
+
// Allocate buffers
|
52
|
+
if (this->start_()) {
|
53
|
+
this->status_clear_warning();
|
54
|
+
}
|
55
|
+
} else {
|
56
|
+
if (!this->status_has_warning()) {
|
57
|
+
this->status_set_warning("Microphone isn't running, can't compute statistics");
|
58
|
+
|
59
|
+
// Deallocate buffers, if necessary
|
60
|
+
this->stop_();
|
61
|
+
|
62
|
+
// Reset sensor outputs
|
63
|
+
if (this->peak_sensor_ != nullptr) {
|
64
|
+
this->peak_sensor_->publish_state(NAN);
|
65
|
+
}
|
66
|
+
if (this->rms_sensor_ != nullptr) {
|
67
|
+
this->rms_sensor_->publish_state(NAN);
|
68
|
+
}
|
69
|
+
|
70
|
+
// Reset accumulators
|
71
|
+
this->squared_peak_ = 0;
|
72
|
+
this->squared_samples_sum_ = 0;
|
73
|
+
this->sample_count_ = 0;
|
74
|
+
}
|
75
|
+
|
76
|
+
return;
|
77
|
+
}
|
78
|
+
|
79
|
+
if (this->status_has_error()) {
|
80
|
+
return;
|
81
|
+
}
|
82
|
+
|
83
|
+
// Copy data from ring buffer into the transfer buffer - don't block to avoid slowing the main loop
|
84
|
+
this->audio_buffer_->transfer_data_from_source(0);
|
85
|
+
|
86
|
+
if (this->audio_buffer_->available() == 0) {
|
87
|
+
// No new audio available for processing
|
88
|
+
return;
|
89
|
+
}
|
90
|
+
|
91
|
+
const uint32_t samples_in_window =
|
92
|
+
this->microphone_source_->get_audio_stream_info().ms_to_samples(this->measurement_duration_ms_);
|
93
|
+
const uint32_t samples_available_to_process =
|
94
|
+
this->microphone_source_->get_audio_stream_info().bytes_to_samples(this->audio_buffer_->available());
|
95
|
+
const uint32_t samples_to_process = std::min(samples_in_window - this->sample_count_, samples_available_to_process);
|
96
|
+
|
97
|
+
// MicrophoneSource always provides int16 samples due to Python codegen settings
|
98
|
+
const int16_t *audio_data = reinterpret_cast<const int16_t *>(this->audio_buffer_->get_buffer_start());
|
99
|
+
|
100
|
+
// Process all the new audio samples
|
101
|
+
for (uint32_t i = 0; i < samples_to_process; ++i) {
|
102
|
+
// Squaring int16 samples won't overflow an int32
|
103
|
+
int32_t squared_sample = static_cast<int32_t>(audio_data[i]) * static_cast<int32_t>(audio_data[i]);
|
104
|
+
|
105
|
+
if (this->peak_sensor_ != nullptr) {
|
106
|
+
this->squared_peak_ = std::max(this->squared_peak_, squared_sample);
|
107
|
+
}
|
108
|
+
|
109
|
+
if (this->rms_sensor_ != nullptr) {
|
110
|
+
// Squared sum is an uint64 type - at max levels, an uint32 type would overflow after ~8 samples
|
111
|
+
this->squared_samples_sum_ += squared_sample;
|
112
|
+
}
|
113
|
+
|
114
|
+
++this->sample_count_;
|
115
|
+
}
|
116
|
+
|
117
|
+
// Remove the processed samples from ``audio_buffer_``
|
118
|
+
this->audio_buffer_->decrease_buffer_length(
|
119
|
+
this->microphone_source_->get_audio_stream_info().samples_to_bytes(samples_to_process));
|
120
|
+
|
121
|
+
if (this->sample_count_ == samples_in_window) {
|
122
|
+
// Processed enough samples for the measurement window, compute and publish the sensor values
|
123
|
+
if (this->peak_sensor_ != nullptr) {
|
124
|
+
const float peak_db = 10.0f * log10(static_cast<float>(this->squared_peak_) / MAX_SAMPLE_SQUARED_DENOMINATOR);
|
125
|
+
this->peak_sensor_->publish_state(peak_db);
|
126
|
+
|
127
|
+
this->squared_peak_ = 0; // reset accumulator
|
128
|
+
}
|
129
|
+
|
130
|
+
if (this->rms_sensor_ != nullptr) {
|
131
|
+
// Calculations are done with doubles instead of floats - floats lose precision for even modest window durations
|
132
|
+
const double rms_db = 10.0 * log10((this->squared_samples_sum_ / MAX_SAMPLE_SQUARED_DENOMINATOR) /
|
133
|
+
static_cast<double>(samples_in_window));
|
134
|
+
this->rms_sensor_->publish_state(rms_db);
|
135
|
+
|
136
|
+
this->squared_samples_sum_ = 0; // reset accumulator
|
137
|
+
}
|
138
|
+
|
139
|
+
this->sample_count_ = 0; // reset counter
|
140
|
+
}
|
141
|
+
}
|
142
|
+
|
143
|
+
void SoundLevelComponent::start() {
|
144
|
+
if (this->microphone_source_->is_passive()) {
|
145
|
+
ESP_LOGW(TAG, "Can't start the microphone in passive mode");
|
146
|
+
return;
|
147
|
+
}
|
148
|
+
this->microphone_source_->start();
|
149
|
+
}
|
150
|
+
|
151
|
+
void SoundLevelComponent::stop() {
|
152
|
+
if (this->microphone_source_->is_passive()) {
|
153
|
+
ESP_LOGW(TAG, "Can't stop microphone in passive mode");
|
154
|
+
return;
|
155
|
+
}
|
156
|
+
this->microphone_source_->stop();
|
157
|
+
}
|
158
|
+
|
159
|
+
bool SoundLevelComponent::start_() {
|
160
|
+
if (this->audio_buffer_ != nullptr) {
|
161
|
+
return true;
|
162
|
+
}
|
163
|
+
|
164
|
+
// Allocate a transfer buffer
|
165
|
+
this->audio_buffer_ = audio::AudioSourceTransferBuffer::create(
|
166
|
+
this->microphone_source_->get_audio_stream_info().ms_to_bytes(AUDIO_BUFFER_DURATION_MS));
|
167
|
+
if (this->audio_buffer_ == nullptr) {
|
168
|
+
this->status_momentary_error("Failed to allocate transfer buffer", 15000);
|
169
|
+
return false;
|
170
|
+
}
|
171
|
+
|
172
|
+
// Allocates a new ring buffer, adds it as a source for the transfer buffer, and points ring_buffer_ to it
|
173
|
+
this->ring_buffer_.reset(); // Reset pointer to any previous ring buffer allocation
|
174
|
+
std::shared_ptr<RingBuffer> temp_ring_buffer =
|
175
|
+
RingBuffer::create(this->microphone_source_->get_audio_stream_info().ms_to_bytes(RING_BUFFER_DURATION_MS));
|
176
|
+
if (temp_ring_buffer.use_count() == 0) {
|
177
|
+
this->status_momentary_error("Failed to allocate ring buffer", 15000);
|
178
|
+
this->stop_();
|
179
|
+
return false;
|
180
|
+
} else {
|
181
|
+
this->ring_buffer_ = temp_ring_buffer;
|
182
|
+
this->audio_buffer_->set_source(temp_ring_buffer);
|
183
|
+
}
|
184
|
+
|
185
|
+
this->status_clear_error();
|
186
|
+
return true;
|
187
|
+
}
|
188
|
+
|
189
|
+
void SoundLevelComponent::stop_() { this->audio_buffer_.reset(); }
|
190
|
+
|
191
|
+
} // namespace sound_level
|
192
|
+
} // namespace esphome
|
193
|
+
|
194
|
+
#endif
|
@@ -0,0 +1,73 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#ifdef USE_ESP32
|
4
|
+
|
5
|
+
#include "esphome/components/audio/audio_transfer_buffer.h"
|
6
|
+
#include "esphome/components/microphone/microphone_source.h"
|
7
|
+
#include "esphome/components/sensor/sensor.h"
|
8
|
+
|
9
|
+
#include "esphome/core/component.h"
|
10
|
+
#include "esphome/core/ring_buffer.h"
|
11
|
+
|
12
|
+
namespace esphome {
|
13
|
+
namespace sound_level {
|
14
|
+
|
15
|
+
class SoundLevelComponent : public Component {
|
16
|
+
public:
|
17
|
+
void dump_config() override;
|
18
|
+
void setup() override;
|
19
|
+
void loop() override;
|
20
|
+
|
21
|
+
float get_setup_priority() const override { return setup_priority::AFTER_CONNECTION; }
|
22
|
+
|
23
|
+
void set_measurement_duration(uint32_t measurement_duration_ms) {
|
24
|
+
this->measurement_duration_ms_ = measurement_duration_ms;
|
25
|
+
}
|
26
|
+
void set_microphone_source(microphone::MicrophoneSource *microphone_source) {
|
27
|
+
this->microphone_source_ = microphone_source;
|
28
|
+
}
|
29
|
+
void set_peak_sensor(sensor::Sensor *peak_sensor) { this->peak_sensor_ = peak_sensor; }
|
30
|
+
void set_rms_sensor(sensor::Sensor *rms_sensor) { this->rms_sensor_ = rms_sensor; }
|
31
|
+
|
32
|
+
/// @brief Starts the MicrophoneSource to start measuring sound levels
|
33
|
+
void start();
|
34
|
+
|
35
|
+
/// @brief Stops the MicrophoneSource
|
36
|
+
void stop();
|
37
|
+
|
38
|
+
protected:
|
39
|
+
/// @brief Internal start command that, if necessary, allocates ``audio_buffer_`` and a ring buffer which
|
40
|
+
/// ``audio_buffer_`` owns and ``ring_buffer_`` points to. Returns true if allocations were successful.
|
41
|
+
bool start_();
|
42
|
+
|
43
|
+
/// @brief Internal stop command the deallocates ``audio_buffer_`` (which automatically deallocates its ring buffer)
|
44
|
+
void stop_();
|
45
|
+
|
46
|
+
microphone::MicrophoneSource *microphone_source_{nullptr};
|
47
|
+
|
48
|
+
sensor::Sensor *peak_sensor_{nullptr};
|
49
|
+
sensor::Sensor *rms_sensor_{nullptr};
|
50
|
+
|
51
|
+
std::unique_ptr<audio::AudioSourceTransferBuffer> audio_buffer_;
|
52
|
+
std::weak_ptr<RingBuffer> ring_buffer_;
|
53
|
+
|
54
|
+
int32_t squared_peak_{0};
|
55
|
+
uint64_t squared_samples_sum_{0};
|
56
|
+
uint32_t sample_count_{0};
|
57
|
+
|
58
|
+
uint32_t measurement_duration_ms_;
|
59
|
+
};
|
60
|
+
|
61
|
+
template<typename... Ts> class StartAction : public Action<Ts...>, public Parented<SoundLevelComponent> {
|
62
|
+
public:
|
63
|
+
void play(Ts... x) override { this->parent_->start(); }
|
64
|
+
};
|
65
|
+
|
66
|
+
template<typename... Ts> class StopAction : public Action<Ts...>, public Parented<SoundLevelComponent> {
|
67
|
+
public:
|
68
|
+
void play(Ts... x) override { this->parent_->stop(); }
|
69
|
+
};
|
70
|
+
|
71
|
+
} // namespace sound_level
|
72
|
+
} // namespace esphome
|
73
|
+
#endif
|
@@ -271,9 +271,8 @@ PIPELINE_SCHEMA = cv.Schema(
|
|
271
271
|
)
|
272
272
|
|
273
273
|
CONFIG_SCHEMA = cv.All(
|
274
|
-
media_player.
|
274
|
+
media_player.media_player_schema(SpeakerMediaPlayer).extend(
|
275
275
|
{
|
276
|
-
cv.GenerateID(): cv.declare_id(SpeakerMediaPlayer),
|
277
276
|
cv.Required(CONF_ANNOUNCEMENT_PIPELINE): PIPELINE_SCHEMA,
|
278
277
|
cv.Optional(CONF_MEDIA_PIPELINE): PIPELINE_SCHEMA,
|
279
278
|
cv.Optional(CONF_BUFFER_SIZE, default=1000000): cv.int_range(
|
@@ -332,22 +331,19 @@ async def to_code(config):
|
|
332
331
|
esp32.add_idf_sdkconfig_option("CONFIG_TCP_MSS", 1436)
|
333
332
|
esp32.add_idf_sdkconfig_option("CONFIG_TCP_MSL", 60000)
|
334
333
|
esp32.add_idf_sdkconfig_option("CONFIG_TCP_SND_BUF_DEFAULT", 65535)
|
335
|
-
esp32.add_idf_sdkconfig_option(
|
336
|
-
"CONFIG_TCP_WND_DEFAULT", 65535
|
337
|
-
) # Adjusted from referenced settings to avoid compilation error
|
334
|
+
esp32.add_idf_sdkconfig_option("CONFIG_TCP_WND_DEFAULT", 512000)
|
338
335
|
esp32.add_idf_sdkconfig_option("CONFIG_TCP_RECVMBOX_SIZE", 512)
|
339
336
|
esp32.add_idf_sdkconfig_option("CONFIG_TCP_QUEUE_OOSEQ", True)
|
340
337
|
esp32.add_idf_sdkconfig_option("CONFIG_TCP_OVERSIZE_MSS", True)
|
341
338
|
esp32.add_idf_sdkconfig_option("CONFIG_LWIP_WND_SCALE", True)
|
342
|
-
esp32.add_idf_sdkconfig_option("
|
339
|
+
esp32.add_idf_sdkconfig_option("CONFIG_LWIP_TCP_RCV_SCALE", 3)
|
343
340
|
esp32.add_idf_sdkconfig_option("CONFIG_LWIP_TCPIP_RECVMBOX_SIZE", 512)
|
344
341
|
|
345
342
|
# Allocate wifi buffers in PSRAM
|
346
343
|
esp32.add_idf_sdkconfig_option("CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP", True)
|
347
344
|
|
348
|
-
var =
|
345
|
+
var = await media_player.new_media_player(config)
|
349
346
|
await cg.register_component(var, config)
|
350
|
-
await media_player.register_media_player(var, config)
|
351
347
|
|
352
348
|
cg.add_define("USE_OTA_STATE_CALLBACK")
|
353
349
|
|
@@ -106,16 +106,6 @@ void SpeakerMediaPlayer::setup() {
|
|
106
106
|
ESP_LOGE(TAG, "Failed to create media pipeline");
|
107
107
|
this->mark_failed();
|
108
108
|
}
|
109
|
-
|
110
|
-
// Setup callback to track the duration of audio played by the media pipeline
|
111
|
-
this->media_speaker_->add_audio_output_callback(
|
112
|
-
[this](uint32_t new_playback_ms, uint32_t remainder_us, uint32_t pending_ms, uint32_t write_timestamp) {
|
113
|
-
this->playback_ms_ += new_playback_ms;
|
114
|
-
this->remainder_us_ = remainder_us;
|
115
|
-
this->pending_ms_ = pending_ms;
|
116
|
-
this->last_audio_write_timestamp_ = write_timestamp;
|
117
|
-
this->playback_us_ = this->playback_ms_ * 1000 + this->remainder_us_;
|
118
|
-
});
|
119
109
|
}
|
120
110
|
|
121
111
|
ESP_LOGI(TAG, "Set up speaker media player");
|
@@ -321,7 +311,6 @@ void SpeakerMediaPlayer::loop() {
|
|
321
311
|
AudioPipelineState old_media_pipeline_state = this->media_pipeline_state_;
|
322
312
|
if (this->media_pipeline_ != nullptr) {
|
323
313
|
this->media_pipeline_state_ = this->media_pipeline_->process_state();
|
324
|
-
this->decoded_playback_ms_ = this->media_pipeline_->get_playback_ms();
|
325
314
|
}
|
326
315
|
|
327
316
|
if (this->media_pipeline_state_ == AudioPipelineState::ERROR_READING) {
|
@@ -379,13 +368,6 @@ void SpeakerMediaPlayer::loop() {
|
|
379
368
|
} else if (this->media_pipeline_state_ == AudioPipelineState::PLAYING) {
|
380
369
|
this->state = media_player::MEDIA_PLAYER_STATE_PLAYING;
|
381
370
|
} else if (this->media_pipeline_state_ == AudioPipelineState::STOPPED) {
|
382
|
-
// Reset playback durations
|
383
|
-
this->decoded_playback_ms_ = 0;
|
384
|
-
this->playback_us_ = 0;
|
385
|
-
this->playback_ms_ = 0;
|
386
|
-
this->remainder_us_ = 0;
|
387
|
-
this->pending_ms_ = 0;
|
388
|
-
|
389
371
|
if (!media_playlist_.empty()) {
|
390
372
|
uint32_t timeout_ms = 0;
|
391
373
|
if (old_media_pipeline_state == AudioPipelineState::PLAYING) {
|
@@ -73,10 +73,6 @@ class SpeakerMediaPlayer : public Component, public media_player::MediaPlayer {
|
|
73
73
|
|
74
74
|
void play_file(audio::AudioFile *media_file, bool announcement, bool enqueue);
|
75
75
|
|
76
|
-
uint32_t get_playback_ms() const { return this->playback_ms_; }
|
77
|
-
uint32_t get_playback_us() const { return this->playback_us_; }
|
78
|
-
uint32_t get_decoded_playback_ms() const { return this->decoded_playback_ms_; }
|
79
|
-
|
80
76
|
void set_playlist_delay_ms(AudioPipelineType pipeline_type, uint32_t delay_ms);
|
81
77
|
|
82
78
|
protected:
|
@@ -141,13 +137,6 @@ class SpeakerMediaPlayer : public Component, public media_player::MediaPlayer {
|
|
141
137
|
Trigger<> *mute_trigger_ = new Trigger<>();
|
142
138
|
Trigger<> *unmute_trigger_ = new Trigger<>();
|
143
139
|
Trigger<float> *volume_trigger_ = new Trigger<float>();
|
144
|
-
|
145
|
-
uint32_t decoded_playback_ms_{0};
|
146
|
-
uint32_t playback_us_{0};
|
147
|
-
uint32_t playback_ms_{0};
|
148
|
-
uint32_t remainder_us_{0};
|
149
|
-
uint32_t pending_ms_{0};
|
150
|
-
uint32_t last_audio_write_timestamp_{0};
|
151
140
|
};
|
152
141
|
|
153
142
|
} // namespace speaker
|
@@ -104,12 +104,9 @@ class Speaker {
|
|
104
104
|
|
105
105
|
/// Callback function for sending the duration of the audio written to the speaker since the last callback.
|
106
106
|
/// Parameters:
|
107
|
-
/// -
|
108
|
-
/// -
|
109
|
-
|
110
|
-
/// - Duration of remaining, unwritten audio buffered in the speaker in milliseconds.
|
111
|
-
/// - System time in microseconds when the last write was completed.
|
112
|
-
void add_audio_output_callback(std::function<void(uint32_t, uint32_t, uint32_t, uint32_t)> &&callback) {
|
107
|
+
/// - Frames played
|
108
|
+
/// - System time in microseconds when the frames were written to the DAC
|
109
|
+
void add_audio_output_callback(std::function<void(uint32_t, int64_t)> &&callback) {
|
113
110
|
this->audio_output_callback_.add(std::move(callback));
|
114
111
|
}
|
115
112
|
|
@@ -123,7 +120,7 @@ class Speaker {
|
|
123
120
|
audio_dac::AudioDac *audio_dac_{nullptr};
|
124
121
|
#endif
|
125
122
|
|
126
|
-
CallbackManager<void(uint32_t,
|
123
|
+
CallbackManager<void(uint32_t, int64_t)> audio_output_callback_{};
|
127
124
|
};
|
128
125
|
|
129
126
|
} // namespace speaker
|
@@ -6,7 +6,6 @@ from esphome.const import (
|
|
6
6
|
CONF_DIRECTION_OUTPUT,
|
7
7
|
CONF_OSCILLATION_OUTPUT,
|
8
8
|
CONF_OUTPUT,
|
9
|
-
CONF_OUTPUT_ID,
|
10
9
|
CONF_PRESET_MODES,
|
11
10
|
CONF_SPEED,
|
12
11
|
CONF_SPEED_COUNT,
|
@@ -16,25 +15,27 @@ from .. import speed_ns
|
|
16
15
|
|
17
16
|
SpeedFan = speed_ns.class_("SpeedFan", cg.Component, fan.Fan)
|
18
17
|
|
19
|
-
CONFIG_SCHEMA =
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
18
|
+
CONFIG_SCHEMA = (
|
19
|
+
fan.fan_schema(SpeedFan)
|
20
|
+
.extend(
|
21
|
+
{
|
22
|
+
cv.Required(CONF_OUTPUT): cv.use_id(output.FloatOutput),
|
23
|
+
cv.Optional(CONF_OSCILLATION_OUTPUT): cv.use_id(output.BinaryOutput),
|
24
|
+
cv.Optional(CONF_DIRECTION_OUTPUT): cv.use_id(output.BinaryOutput),
|
25
|
+
cv.Optional(CONF_SPEED): cv.invalid(
|
26
|
+
"Configuring individual speeds is deprecated."
|
27
|
+
),
|
28
|
+
cv.Optional(CONF_SPEED_COUNT, default=100): cv.int_range(min=1),
|
29
|
+
cv.Optional(CONF_PRESET_MODES): validate_preset_modes,
|
30
|
+
}
|
31
|
+
)
|
32
|
+
.extend(cv.COMPONENT_SCHEMA)
|
33
|
+
)
|
32
34
|
|
33
35
|
|
34
36
|
async def to_code(config):
|
35
|
-
var =
|
37
|
+
var = await fan.new_fan(config, config[CONF_SPEED_COUNT])
|
36
38
|
await cg.register_component(var, config)
|
37
|
-
await fan.register_fan(var, config)
|
38
39
|
|
39
40
|
output_ = await cg.get_variable(config[CONF_OUTPUT])
|
40
41
|
cg.add(var.set_output(output_))
|
esphome/components/spi/spi.h
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
#pragma once
|
2
|
-
|
3
2
|
#include "esphome/core/application.h"
|
4
3
|
#include "esphome/core/component.h"
|
5
4
|
#include "esphome/core/hal.h"
|
@@ -28,6 +27,11 @@ using SPIInterface = spi_host_device_t;
|
|
28
27
|
|
29
28
|
#endif // USE_ESP_IDF
|
30
29
|
|
30
|
+
#ifdef USE_ZEPHYR
|
31
|
+
// TODO supprse clang-tidy. Remove after SPI driver for nrf52 is added.
|
32
|
+
using SPIInterface = void *;
|
33
|
+
#endif
|
34
|
+
|
31
35
|
/**
|
32
36
|
* Implementation of SPI Controller mode.
|
33
37
|
*/
|
@@ -351,6 +355,12 @@ class SPIComponent : public Component {
|
|
351
355
|
|
352
356
|
void setup() override;
|
353
357
|
void dump_config() override;
|
358
|
+
size_t get_bus_width() const {
|
359
|
+
if (this->data_pins_.empty()) {
|
360
|
+
return 1;
|
361
|
+
}
|
362
|
+
return this->data_pins_.size();
|
363
|
+
}
|
354
364
|
|
355
365
|
protected:
|
356
366
|
GPIOPin *clk_pin_{nullptr};
|