esphome 2025.4.1__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/as3935_i2c/as3935_i2c.h +0 -3
- 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/display/rect.cpp +4 -9
- esphome/components/display/rect.h +1 -1
- 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 -8
- 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/hlw8012/hlw8012.cpp +1 -1
- 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/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/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 +40 -6
- 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/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/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.1.dist-info → esphome-2025.5.0.dist-info}/METADATA +10 -11
- {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/RECORD +456 -396
- {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/WHEEL +1 -1
- esphome/components/esp32_ble/const_esp32c6.h +0 -74
- {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/entry_points.txt +0 -0
- {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/top_level.txt +0 -0
@@ -33,6 +33,7 @@ from esphome.const import (
|
|
33
33
|
UNIT_PERCENT,
|
34
34
|
)
|
35
35
|
|
36
|
+
CODEOWNERS = ["@ximex"]
|
36
37
|
DEPENDENCIES = ["uart"]
|
37
38
|
|
38
39
|
pmsx003_ns = cg.esphome_ns.namespace("pmsx003")
|
@@ -57,9 +58,18 @@ SENSORS_TO_TYPE = {
|
|
57
58
|
CONF_PM_1_0: [TYPE_PMSX003, TYPE_PMS5003T, TYPE_PMS5003ST, TYPE_PMS5003S],
|
58
59
|
CONF_PM_2_5: [TYPE_PMSX003, TYPE_PMS5003T, TYPE_PMS5003ST, TYPE_PMS5003S],
|
59
60
|
CONF_PM_10_0: [TYPE_PMSX003, TYPE_PMS5003T, TYPE_PMS5003ST, TYPE_PMS5003S],
|
61
|
+
CONF_PM_1_0_STD: [TYPE_PMSX003, TYPE_PMS5003T, TYPE_PMS5003ST, TYPE_PMS5003S],
|
62
|
+
CONF_PM_2_5_STD: [TYPE_PMSX003, TYPE_PMS5003T, TYPE_PMS5003ST, TYPE_PMS5003S],
|
63
|
+
CONF_PM_10_0_STD: [TYPE_PMSX003, TYPE_PMS5003T, TYPE_PMS5003ST, TYPE_PMS5003S],
|
64
|
+
CONF_PM_0_3UM: [TYPE_PMSX003, TYPE_PMS5003T, TYPE_PMS5003ST, TYPE_PMS5003S],
|
65
|
+
CONF_PM_0_5UM: [TYPE_PMSX003, TYPE_PMS5003T, TYPE_PMS5003ST, TYPE_PMS5003S],
|
66
|
+
CONF_PM_1_0UM: [TYPE_PMSX003, TYPE_PMS5003T, TYPE_PMS5003ST, TYPE_PMS5003S],
|
67
|
+
CONF_PM_2_5UM: [TYPE_PMSX003, TYPE_PMS5003T, TYPE_PMS5003ST, TYPE_PMS5003S],
|
68
|
+
CONF_PM_5_0UM: [TYPE_PMSX003, TYPE_PMS5003ST, TYPE_PMS5003S],
|
69
|
+
CONF_PM_10_0UM: [TYPE_PMSX003, TYPE_PMS5003ST, TYPE_PMS5003S],
|
70
|
+
CONF_FORMALDEHYDE: [TYPE_PMS5003ST, TYPE_PMS5003S],
|
60
71
|
CONF_TEMPERATURE: [TYPE_PMS5003T, TYPE_PMS5003ST],
|
61
72
|
CONF_HUMIDITY: [TYPE_PMS5003T, TYPE_PMS5003ST],
|
62
|
-
CONF_FORMALDEHYDE: [TYPE_PMS5003ST, TYPE_PMS5003S],
|
63
73
|
}
|
64
74
|
|
65
75
|
|
@@ -164,6 +174,12 @@ CONFIG_SCHEMA = (
|
|
164
174
|
accuracy_decimals=0,
|
165
175
|
state_class=STATE_CLASS_MEASUREMENT,
|
166
176
|
),
|
177
|
+
cv.Optional(CONF_FORMALDEHYDE): sensor.sensor_schema(
|
178
|
+
unit_of_measurement=UNIT_MICROGRAMS_PER_CUBIC_METER,
|
179
|
+
icon=ICON_CHEMICAL_WEAPON,
|
180
|
+
accuracy_decimals=0,
|
181
|
+
state_class=STATE_CLASS_MEASUREMENT,
|
182
|
+
),
|
167
183
|
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
|
168
184
|
unit_of_measurement=UNIT_CELSIUS,
|
169
185
|
accuracy_decimals=1,
|
@@ -176,12 +192,6 @@ CONFIG_SCHEMA = (
|
|
176
192
|
device_class=DEVICE_CLASS_HUMIDITY,
|
177
193
|
state_class=STATE_CLASS_MEASUREMENT,
|
178
194
|
),
|
179
|
-
cv.Optional(CONF_FORMALDEHYDE): sensor.sensor_schema(
|
180
|
-
unit_of_measurement=UNIT_MICROGRAMS_PER_CUBIC_METER,
|
181
|
-
icon=ICON_CHEMICAL_WEAPON,
|
182
|
-
accuracy_decimals=0,
|
183
|
-
state_class=STATE_CLASS_MEASUREMENT,
|
184
|
-
),
|
185
195
|
cv.Optional(CONF_UPDATE_INTERVAL, default="0s"): validate_update_interval,
|
186
196
|
}
|
187
197
|
)
|
@@ -256,6 +266,10 @@ async def to_code(config):
|
|
256
266
|
sens = await sensor.new_sensor(config[CONF_PM_10_0UM])
|
257
267
|
cg.add(var.set_pm_particles_100um_sensor(sens))
|
258
268
|
|
269
|
+
if CONF_FORMALDEHYDE in config:
|
270
|
+
sens = await sensor.new_sensor(config[CONF_FORMALDEHYDE])
|
271
|
+
cg.add(var.set_formaldehyde_sensor(sens))
|
272
|
+
|
259
273
|
if CONF_TEMPERATURE in config:
|
260
274
|
sens = await sensor.new_sensor(config[CONF_TEMPERATURE])
|
261
275
|
cg.add(var.set_temperature_sensor(sens))
|
@@ -264,8 +278,4 @@ async def to_code(config):
|
|
264
278
|
sens = await sensor.new_sensor(config[CONF_HUMIDITY])
|
265
279
|
cg.add(var.set_humidity_sensor(sens))
|
266
280
|
|
267
|
-
if CONF_FORMALDEHYDE in config:
|
268
|
-
sens = await sensor.new_sensor(config[CONF_FORMALDEHYDE])
|
269
|
-
cg.add(var.set_formaldehyde_sensor(sens))
|
270
|
-
|
271
281
|
cg.add(var.set_update_interval(config[CONF_UPDATE_INTERVAL]))
|
@@ -89,6 +89,12 @@ void PrometheusHandler::handleRequest(AsyncWebServerRequest *req) {
|
|
89
89
|
this->valve_row_(stream, obj, area, node, friendly_name);
|
90
90
|
#endif
|
91
91
|
|
92
|
+
#ifdef USE_CLIMATE
|
93
|
+
this->climate_type_(stream);
|
94
|
+
for (auto *obj : App.get_climates())
|
95
|
+
this->climate_row_(stream, obj, area, node, friendly_name);
|
96
|
+
#endif
|
97
|
+
|
92
98
|
req->send(stream);
|
93
99
|
}
|
94
100
|
|
@@ -824,6 +830,174 @@ void PrometheusHandler::valve_row_(AsyncResponseStream *stream, valve::Valve *ob
|
|
824
830
|
}
|
825
831
|
#endif
|
826
832
|
|
833
|
+
#ifdef USE_CLIMATE
|
834
|
+
void PrometheusHandler::climate_type_(AsyncResponseStream *stream) {
|
835
|
+
stream->print(F("#TYPE esphome_climate_setting gauge\n"));
|
836
|
+
stream->print(F("#TYPE esphome_climate_value gauge\n"));
|
837
|
+
stream->print(F("#TYPE esphome_climate_failed gauge\n"));
|
838
|
+
}
|
839
|
+
|
840
|
+
void PrometheusHandler::climate_setting_row_(AsyncResponseStream *stream, climate::Climate *obj, std::string &area,
|
841
|
+
std::string &node, std::string &friendly_name, std::string &setting,
|
842
|
+
const LogString *setting_value) {
|
843
|
+
stream->print(F("esphome_climate_setting{id=\""));
|
844
|
+
stream->print(relabel_id_(obj).c_str());
|
845
|
+
add_area_label_(stream, area);
|
846
|
+
add_node_label_(stream, node);
|
847
|
+
add_friendly_name_label_(stream, friendly_name);
|
848
|
+
stream->print(F("\",name=\""));
|
849
|
+
stream->print(relabel_name_(obj).c_str());
|
850
|
+
stream->print(F("\",category=\""));
|
851
|
+
stream->print(setting.c_str());
|
852
|
+
stream->print(F("\",setting_value=\""));
|
853
|
+
stream->print(LOG_STR_ARG(setting_value));
|
854
|
+
stream->print(F("\"} "));
|
855
|
+
stream->print(F("1.0"));
|
856
|
+
stream->print(F("\n"));
|
857
|
+
}
|
858
|
+
|
859
|
+
void PrometheusHandler::climate_value_row_(AsyncResponseStream *stream, climate::Climate *obj, std::string &area,
|
860
|
+
std::string &node, std::string &friendly_name, std::string &category,
|
861
|
+
std::string &climate_value) {
|
862
|
+
stream->print(F("esphome_climate_value{id=\""));
|
863
|
+
stream->print(relabel_id_(obj).c_str());
|
864
|
+
add_area_label_(stream, area);
|
865
|
+
add_node_label_(stream, node);
|
866
|
+
add_friendly_name_label_(stream, friendly_name);
|
867
|
+
stream->print(F("\",name=\""));
|
868
|
+
stream->print(relabel_name_(obj).c_str());
|
869
|
+
stream->print(F("\",category=\""));
|
870
|
+
stream->print(category.c_str());
|
871
|
+
stream->print(F("\"} "));
|
872
|
+
stream->print(climate_value.c_str());
|
873
|
+
stream->print(F("\n"));
|
874
|
+
}
|
875
|
+
|
876
|
+
void PrometheusHandler::climate_failed_row_(AsyncResponseStream *stream, climate::Climate *obj, std::string &area,
|
877
|
+
std::string &node, std::string &friendly_name, std::string &category,
|
878
|
+
bool is_failed_value) {
|
879
|
+
stream->print(F("esphome_climate_failed{id=\""));
|
880
|
+
stream->print(relabel_id_(obj).c_str());
|
881
|
+
add_area_label_(stream, area);
|
882
|
+
add_node_label_(stream, node);
|
883
|
+
add_friendly_name_label_(stream, friendly_name);
|
884
|
+
stream->print(F("\",name=\""));
|
885
|
+
stream->print(relabel_name_(obj).c_str());
|
886
|
+
stream->print(F("\",category=\""));
|
887
|
+
stream->print(category.c_str());
|
888
|
+
stream->print(F("\"} "));
|
889
|
+
if (is_failed_value) {
|
890
|
+
stream->print(F("1.0"));
|
891
|
+
} else {
|
892
|
+
stream->print(F("0.0"));
|
893
|
+
}
|
894
|
+
stream->print(F("\n"));
|
895
|
+
}
|
896
|
+
|
897
|
+
void PrometheusHandler::climate_row_(AsyncResponseStream *stream, climate::Climate *obj, std::string &area,
|
898
|
+
std::string &node, std::string &friendly_name) {
|
899
|
+
if (obj->is_internal() && !this->include_internal_)
|
900
|
+
return;
|
901
|
+
// Data itself
|
902
|
+
bool any_failures = false;
|
903
|
+
std::string climate_mode_category = "mode";
|
904
|
+
const auto *climate_mode_value = climate::climate_mode_to_string(obj->mode);
|
905
|
+
climate_setting_row_(stream, obj, area, node, friendly_name, climate_mode_category, climate_mode_value);
|
906
|
+
const auto traits = obj->get_traits();
|
907
|
+
// Now see if traits is supported
|
908
|
+
int8_t target_accuracy = traits.get_target_temperature_accuracy_decimals();
|
909
|
+
int8_t current_accuracy = traits.get_current_temperature_accuracy_decimals();
|
910
|
+
// max temp
|
911
|
+
std::string max_temp = "maximum_temperature";
|
912
|
+
auto max_temp_value = value_accuracy_to_string(traits.get_visual_max_temperature(), target_accuracy);
|
913
|
+
climate_value_row_(stream, obj, area, node, friendly_name, max_temp, max_temp_value);
|
914
|
+
// max temp
|
915
|
+
std::string min_temp = "mininum_temperature";
|
916
|
+
auto min_temp_value = value_accuracy_to_string(traits.get_visual_min_temperature(), target_accuracy);
|
917
|
+
climate_value_row_(stream, obj, area, node, friendly_name, min_temp, min_temp_value);
|
918
|
+
// now check optional traits
|
919
|
+
if (traits.get_supports_current_temperature()) {
|
920
|
+
std::string current_temp = "current_temperature";
|
921
|
+
if (std::isnan(obj->current_temperature)) {
|
922
|
+
climate_failed_row_(stream, obj, area, node, friendly_name, current_temp, true);
|
923
|
+
any_failures = true;
|
924
|
+
} else {
|
925
|
+
auto current_temp_value = value_accuracy_to_string(obj->current_temperature, current_accuracy);
|
926
|
+
climate_value_row_(stream, obj, area, node, friendly_name, current_temp, current_temp_value);
|
927
|
+
climate_failed_row_(stream, obj, area, node, friendly_name, current_temp, false);
|
928
|
+
}
|
929
|
+
}
|
930
|
+
if (traits.get_supports_current_humidity()) {
|
931
|
+
std::string current_humidity = "current_humidity";
|
932
|
+
if (std::isnan(obj->current_humidity)) {
|
933
|
+
climate_failed_row_(stream, obj, area, node, friendly_name, current_humidity, true);
|
934
|
+
any_failures = true;
|
935
|
+
} else {
|
936
|
+
auto current_humidity_value = value_accuracy_to_string(obj->current_humidity, 0);
|
937
|
+
climate_value_row_(stream, obj, area, node, friendly_name, current_humidity, current_humidity_value);
|
938
|
+
climate_failed_row_(stream, obj, area, node, friendly_name, current_humidity, false);
|
939
|
+
}
|
940
|
+
}
|
941
|
+
if (traits.get_supports_target_humidity()) {
|
942
|
+
std::string target_humidity = "target_humidity";
|
943
|
+
if (std::isnan(obj->target_humidity)) {
|
944
|
+
climate_failed_row_(stream, obj, area, node, friendly_name, target_humidity, true);
|
945
|
+
any_failures = true;
|
946
|
+
} else {
|
947
|
+
auto target_humidity_value = value_accuracy_to_string(obj->target_humidity, 0);
|
948
|
+
climate_value_row_(stream, obj, area, node, friendly_name, target_humidity, target_humidity_value);
|
949
|
+
climate_failed_row_(stream, obj, area, node, friendly_name, target_humidity, false);
|
950
|
+
}
|
951
|
+
}
|
952
|
+
if (traits.get_supports_two_point_target_temperature()) {
|
953
|
+
std::string target_temp_low = "target_temperature_low";
|
954
|
+
auto target_temp_low_value = value_accuracy_to_string(obj->target_temperature_low, target_accuracy);
|
955
|
+
climate_value_row_(stream, obj, area, node, friendly_name, target_temp_low, target_temp_low_value);
|
956
|
+
std::string target_temp_high = "target_temperature_high";
|
957
|
+
auto target_temp_high_value = value_accuracy_to_string(obj->target_temperature_high, target_accuracy);
|
958
|
+
climate_value_row_(stream, obj, area, node, friendly_name, target_temp_high, target_temp_high_value);
|
959
|
+
} else {
|
960
|
+
std::string target_temp = "target_temperature";
|
961
|
+
auto target_temp_value = value_accuracy_to_string(obj->target_temperature, target_accuracy);
|
962
|
+
climate_value_row_(stream, obj, area, node, friendly_name, target_temp, target_temp_value);
|
963
|
+
}
|
964
|
+
if (traits.get_supports_action()) {
|
965
|
+
std::string climate_trait_category = "action";
|
966
|
+
const auto *climate_trait_value = climate::climate_action_to_string(obj->action);
|
967
|
+
climate_setting_row_(stream, obj, area, node, friendly_name, climate_trait_category, climate_trait_value);
|
968
|
+
}
|
969
|
+
if (traits.get_supports_fan_modes()) {
|
970
|
+
std::string climate_trait_category = "fan_mode";
|
971
|
+
if (obj->fan_mode.has_value()) {
|
972
|
+
const auto *climate_trait_value = climate::climate_fan_mode_to_string(obj->fan_mode.value());
|
973
|
+
climate_setting_row_(stream, obj, area, node, friendly_name, climate_trait_category, climate_trait_value);
|
974
|
+
climate_failed_row_(stream, obj, area, node, friendly_name, climate_trait_category, false);
|
975
|
+
} else {
|
976
|
+
climate_failed_row_(stream, obj, area, node, friendly_name, climate_trait_category, true);
|
977
|
+
any_failures = true;
|
978
|
+
}
|
979
|
+
}
|
980
|
+
if (traits.get_supports_presets()) {
|
981
|
+
std::string climate_trait_category = "preset";
|
982
|
+
if (obj->preset.has_value()) {
|
983
|
+
const auto *climate_trait_value = climate::climate_preset_to_string(obj->preset.value());
|
984
|
+
climate_setting_row_(stream, obj, area, node, friendly_name, climate_trait_category, climate_trait_value);
|
985
|
+
climate_failed_row_(stream, obj, area, node, friendly_name, climate_trait_category, false);
|
986
|
+
} else {
|
987
|
+
climate_failed_row_(stream, obj, area, node, friendly_name, climate_trait_category, true);
|
988
|
+
any_failures = true;
|
989
|
+
}
|
990
|
+
}
|
991
|
+
if (traits.get_supports_swing_modes()) {
|
992
|
+
std::string climate_trait_category = "swing_mode";
|
993
|
+
const auto *climate_trait_value = climate::climate_swing_mode_to_string(obj->swing_mode);
|
994
|
+
climate_setting_row_(stream, obj, area, node, friendly_name, climate_trait_category, climate_trait_value);
|
995
|
+
}
|
996
|
+
std::string all_climate_category = "all";
|
997
|
+
climate_failed_row_(stream, obj, area, node, friendly_name, all_climate_category, any_failures);
|
998
|
+
}
|
999
|
+
#endif
|
1000
|
+
|
827
1001
|
} // namespace prometheus
|
828
1002
|
} // namespace esphome
|
829
1003
|
#endif
|
@@ -8,6 +8,9 @@
|
|
8
8
|
#include "esphome/core/component.h"
|
9
9
|
#include "esphome/core/controller.h"
|
10
10
|
#include "esphome/core/entity_base.h"
|
11
|
+
#ifdef USE_CLIMATE
|
12
|
+
#include "esphome/core/log.h"
|
13
|
+
#endif
|
11
14
|
|
12
15
|
namespace esphome {
|
13
16
|
namespace prometheus {
|
@@ -169,6 +172,20 @@ class PrometheusHandler : public AsyncWebHandler, public Component {
|
|
169
172
|
std::string &friendly_name);
|
170
173
|
#endif
|
171
174
|
|
175
|
+
#ifdef USE_CLIMATE
|
176
|
+
/// Return the type for prometheus
|
177
|
+
void climate_type_(AsyncResponseStream *stream);
|
178
|
+
/// Return the climate state as prometheus data point
|
179
|
+
void climate_row_(AsyncResponseStream *stream, climate::Climate *obj, std::string &area, std::string &node,
|
180
|
+
std::string &friendly_name);
|
181
|
+
void climate_failed_row_(AsyncResponseStream *stream, climate::Climate *obj, std::string &area, std::string &node,
|
182
|
+
std::string &friendly_name, std::string &category, bool is_failed_value);
|
183
|
+
void climate_setting_row_(AsyncResponseStream *stream, climate::Climate *obj, std::string &area, std::string &node,
|
184
|
+
std::string &friendly_name, std::string &setting, const LogString *setting_value);
|
185
|
+
void climate_value_row_(AsyncResponseStream *stream, climate::Climate *obj, std::string &area, std::string &node,
|
186
|
+
std::string &friendly_name, std::string &category, std::string &climate_value);
|
187
|
+
#endif
|
188
|
+
|
172
189
|
web_server_base::WebServerBase *base_;
|
173
190
|
bool include_internal_{false};
|
174
191
|
std::map<EntityBase *, std::string> relabel_map_id_;
|
@@ -16,6 +16,8 @@ from esphome.const import (
|
|
16
16
|
CONF_ID,
|
17
17
|
CONF_MODE,
|
18
18
|
CONF_SPEED,
|
19
|
+
KEY_CORE,
|
20
|
+
KEY_FRAMEWORK_VERSION,
|
19
21
|
PLATFORM_ESP32,
|
20
22
|
)
|
21
23
|
from esphome.core import CORE
|
@@ -110,11 +112,11 @@ async def to_code(config):
|
|
110
112
|
add_idf_sdkconfig_option(f"{SPIRAM_MODES[config[CONF_MODE]]}", True)
|
111
113
|
add_idf_sdkconfig_option(f"{SPIRAM_SPEEDS[config[CONF_SPEED]]}", True)
|
112
114
|
if config[CONF_MODE] == TYPE_OCTAL and config[CONF_SPEED] == 120e6:
|
113
|
-
add_idf_sdkconfig_option("
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
115
|
+
add_idf_sdkconfig_option("CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240", True)
|
116
|
+
if CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION] >= cv.Version(5, 4, 0):
|
117
|
+
add_idf_sdkconfig_option(
|
118
|
+
"CONFIG_SPIRAM_TIMING_TUNING_POINT_VIA_TEMPERATURE_SENSOR", True
|
119
|
+
)
|
118
120
|
if config[CONF_ENABLE_ECC]:
|
119
121
|
add_idf_sdkconfig_option("CONFIG_SPIRAM_ECC_ENABLE", True)
|
120
122
|
|
@@ -18,6 +18,9 @@ void PulseMeterSensor::setup() {
|
|
18
18
|
this->pin_->setup();
|
19
19
|
this->isr_pin_ = pin_->to_isr();
|
20
20
|
|
21
|
+
// Set the pin value to the current value to avoid a false edge
|
22
|
+
this->last_pin_val_ = this->pin_->digital_read();
|
23
|
+
|
21
24
|
// Set the last processed edge to now for the first timeout
|
22
25
|
this->last_processed_edge_us_ = micros();
|
23
26
|
|
@@ -25,23 +28,37 @@ void PulseMeterSensor::setup() {
|
|
25
28
|
this->pin_->attach_interrupt(PulseMeterSensor::edge_intr, this, gpio::INTERRUPT_RISING_EDGE);
|
26
29
|
} else if (this->filter_mode_ == FILTER_PULSE) {
|
27
30
|
// Set the pin value to the current value to avoid a false edge
|
28
|
-
this->pulse_state_.
|
29
|
-
this->pulse_state_.latched_ = this->pulse_state_.last_pin_val_;
|
31
|
+
this->pulse_state_.latched_ = this->last_pin_val_;
|
30
32
|
this->pin_->attach_interrupt(PulseMeterSensor::pulse_intr, this, gpio::INTERRUPT_ANY_EDGE);
|
31
33
|
}
|
32
34
|
}
|
33
35
|
|
34
36
|
void PulseMeterSensor::loop() {
|
35
|
-
const uint32_t now = micros();
|
36
|
-
|
37
37
|
// Reset the count in get before we pass it back to the ISR as set
|
38
38
|
this->get_->count_ = 0;
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
40
|
+
{
|
41
|
+
// Lock the interrupt so the interrupt code doesn't interfere with itself
|
42
|
+
InterruptLock lock;
|
43
|
+
|
44
|
+
// Sometimes ESP devices miss interrupts if the edge rises or falls too slowly.
|
45
|
+
// See https://github.com/espressif/arduino-esp32/issues/4172
|
46
|
+
// If the edges are rising too slowly it also implies that the pulse rate is slow.
|
47
|
+
// Therefore the update rate of the loop is likely fast enough to detect the edges.
|
48
|
+
// When the main loop detects an edge that the ISR didn't it will run the ISR functions directly.
|
49
|
+
bool current = this->pin_->digital_read();
|
50
|
+
if (this->filter_mode_ == FILTER_EDGE && current && !this->last_pin_val_) {
|
51
|
+
PulseMeterSensor::edge_intr(this);
|
52
|
+
} else if (this->filter_mode_ == FILTER_PULSE && current != this->last_pin_val_) {
|
53
|
+
PulseMeterSensor::pulse_intr(this);
|
54
|
+
}
|
55
|
+
this->last_pin_val_ = current;
|
56
|
+
|
57
|
+
// Swap out set and get to get the latest state from the ISR
|
58
|
+
std::swap(this->set_, this->get_);
|
59
|
+
}
|
60
|
+
|
61
|
+
const uint32_t now = micros();
|
45
62
|
|
46
63
|
// If an edge was peeked, repay the debt
|
47
64
|
if (this->peeked_edge_ && this->get_->count_ > 0) {
|
@@ -131,6 +148,9 @@ void IRAM_ATTR PulseMeterSensor::edge_intr(PulseMeterSensor *sensor) {
|
|
131
148
|
set.last_rising_edge_us_ = now;
|
132
149
|
set.count_++;
|
133
150
|
}
|
151
|
+
|
152
|
+
// This ISR is bound to rising edges, so the pin is high
|
153
|
+
sensor->last_pin_val_ = true;
|
134
154
|
}
|
135
155
|
|
136
156
|
void IRAM_ATTR PulseMeterSensor::pulse_intr(PulseMeterSensor *sensor) {
|
@@ -144,9 +164,9 @@ void IRAM_ATTR PulseMeterSensor::pulse_intr(PulseMeterSensor *sensor) {
|
|
144
164
|
// Filter length has passed since the last interrupt
|
145
165
|
const bool length = now - state.last_intr_ >= sensor->filter_us_;
|
146
166
|
|
147
|
-
if (length && state.latched_ && !
|
167
|
+
if (length && state.latched_ && !sensor->last_pin_val_) { // Long enough low edge
|
148
168
|
state.latched_ = false;
|
149
|
-
} else if (length && !state.latched_ &&
|
169
|
+
} else if (length && !state.latched_ && sensor->last_pin_val_) { // Long enough high edge
|
150
170
|
state.latched_ = true;
|
151
171
|
set.last_detected_edge_us_ = state.last_intr_;
|
152
172
|
set.count_++;
|
@@ -158,7 +178,7 @@ void IRAM_ATTR PulseMeterSensor::pulse_intr(PulseMeterSensor *sensor) {
|
|
158
178
|
set.last_rising_edge_us_ = !state.latched_ && pin_val ? now : set.last_detected_edge_us_;
|
159
179
|
|
160
180
|
state.last_intr_ = now;
|
161
|
-
|
181
|
+
sensor->last_pin_val_ = pin_val;
|
162
182
|
}
|
163
183
|
|
164
184
|
} // namespace pulse_meter
|
@@ -49,9 +49,7 @@ class PulseMeterSensor : public sensor::Sensor, public Component {
|
|
49
49
|
|
50
50
|
// This struct (and the two pointers) are used to pass data between the ISR and loop.
|
51
51
|
// These two pointers are exchanged each loop.
|
52
|
-
//
|
53
|
-
// As a result it's easiest if you only use these pointers to send data from the ISR to the loop.
|
54
|
-
// (except for resetting the values)
|
52
|
+
// Use these to send data from the ISR to the loop not the other way around (except for resetting the values).
|
55
53
|
struct State {
|
56
54
|
uint32_t last_detected_edge_us_ = 0;
|
57
55
|
uint32_t last_rising_edge_us_ = 0;
|
@@ -61,9 +59,12 @@ class PulseMeterSensor : public sensor::Sensor, public Component {
|
|
61
59
|
volatile State *set_ = state_;
|
62
60
|
volatile State *get_ = state_ + 1;
|
63
61
|
|
64
|
-
// Only use
|
62
|
+
// Only use the following variables in the ISR or while guarded by an InterruptLock
|
65
63
|
ISRInternalGPIOPin isr_pin_;
|
66
64
|
|
65
|
+
/// The last pin value seen
|
66
|
+
bool last_pin_val_ = false;
|
67
|
+
|
67
68
|
/// Filter state for edge mode
|
68
69
|
struct EdgeState {
|
69
70
|
uint32_t last_sent_edge_us_ = 0;
|
@@ -74,7 +75,6 @@ class PulseMeterSensor : public sensor::Sensor, public Component {
|
|
74
75
|
struct PulseState {
|
75
76
|
uint32_t last_intr_ = 0;
|
76
77
|
bool latched_ = false;
|
77
|
-
bool last_pin_val_ = false;
|
78
78
|
};
|
79
79
|
PulseState pulse_state_{};
|
80
80
|
};
|
@@ -1,5 +1,6 @@
|
|
1
1
|
#include "pzem004t.h"
|
2
2
|
#include "esphome/core/log.h"
|
3
|
+
#include "esphome/core/application.h"
|
3
4
|
#include <cinttypes>
|
4
5
|
|
5
6
|
namespace esphome {
|
@@ -16,7 +17,7 @@ void PZEM004T::setup() {
|
|
16
17
|
}
|
17
18
|
|
18
19
|
void PZEM004T::loop() {
|
19
|
-
const uint32_t now =
|
20
|
+
const uint32_t now = App.get_loop_component_start_time();
|
20
21
|
if (now - this->last_read_ > 500 && this->available() < 7) {
|
21
22
|
while (this->available())
|
22
23
|
this->read();
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from esphome import pins
|
2
2
|
import esphome.codegen as cg
|
3
3
|
from esphome.components import display, spi
|
4
|
+
from esphome.components.const import CONF_DRAW_ROUNDING
|
4
5
|
import esphome.config_validation as cv
|
5
6
|
from esphome.const import (
|
6
7
|
CONF_BRIGHTNESS,
|
@@ -24,7 +25,7 @@ from esphome.const import (
|
|
24
25
|
)
|
25
26
|
from esphome.core import TimePeriod
|
26
27
|
|
27
|
-
from . import CONF_DRAW_FROM_ORIGIN
|
28
|
+
from . import CONF_DRAW_FROM_ORIGIN
|
28
29
|
from .models import DriverChip
|
29
30
|
|
30
31
|
DEPENDENCIES = ["spi"]
|
@@ -28,6 +28,7 @@ from esphome.const import (
|
|
28
28
|
CONF_RC_CODE_2,
|
29
29
|
CONF_REPEAT,
|
30
30
|
CONF_SECOND,
|
31
|
+
CONF_SOURCE,
|
31
32
|
CONF_STATE,
|
32
33
|
CONF_SYNC,
|
33
34
|
CONF_TIMES,
|
@@ -265,6 +266,53 @@ async def build_dumpers(config):
|
|
265
266
|
return dumpers
|
266
267
|
|
267
268
|
|
269
|
+
# Beo4
|
270
|
+
Beo4Data, Beo4BinarySensor, Beo4Trigger, Beo4Action, Beo4Dumper = declare_protocol(
|
271
|
+
"Beo4"
|
272
|
+
)
|
273
|
+
BEO4_SCHEMA = cv.Schema(
|
274
|
+
{
|
275
|
+
cv.Required(CONF_SOURCE): cv.hex_uint8_t,
|
276
|
+
cv.Required(CONF_COMMAND): cv.hex_uint8_t,
|
277
|
+
cv.Optional(CONF_COMMAND_REPEATS, default=1): cv.uint8_t,
|
278
|
+
}
|
279
|
+
)
|
280
|
+
|
281
|
+
|
282
|
+
@register_binary_sensor("beo4", Beo4BinarySensor, BEO4_SCHEMA)
|
283
|
+
def beo4_binary_sensor(var, config):
|
284
|
+
cg.add(
|
285
|
+
var.set_data(
|
286
|
+
cg.StructInitializer(
|
287
|
+
Beo4Data,
|
288
|
+
("source", config[CONF_SOURCE]),
|
289
|
+
("command", config[CONF_COMMAND]),
|
290
|
+
("repeats", config[CONF_COMMAND_REPEATS]),
|
291
|
+
)
|
292
|
+
)
|
293
|
+
)
|
294
|
+
|
295
|
+
|
296
|
+
@register_trigger("beo4", Beo4Trigger, Beo4Data)
|
297
|
+
def beo4_trigger(var, config):
|
298
|
+
pass
|
299
|
+
|
300
|
+
|
301
|
+
@register_dumper("beo4", Beo4Dumper)
|
302
|
+
def beo4_dumper(var, config):
|
303
|
+
pass
|
304
|
+
|
305
|
+
|
306
|
+
@register_action("beo4", Beo4Action, BEO4_SCHEMA)
|
307
|
+
async def beo4_action(var, config, args):
|
308
|
+
template_ = await cg.templatable(config[CONF_SOURCE], args, cg.uint8)
|
309
|
+
cg.add(var.set_source(template_))
|
310
|
+
template_ = await cg.templatable(config[CONF_COMMAND], args, cg.uint8)
|
311
|
+
cg.add(var.set_command(template_))
|
312
|
+
template_ = await cg.templatable(config[CONF_COMMAND_REPEATS], args, cg.uint8)
|
313
|
+
cg.add(var.set_repeats(template_))
|
314
|
+
|
315
|
+
|
268
316
|
# ByronSX
|
269
317
|
(
|
270
318
|
ByronSXData,
|
@@ -881,6 +929,49 @@ async def pronto_action(var, config, args):
|
|
881
929
|
cg.add(var.set_data(template_))
|
882
930
|
|
883
931
|
|
932
|
+
# Gobox
|
933
|
+
(
|
934
|
+
GoboxData,
|
935
|
+
GoboxBinarySensor,
|
936
|
+
GoboxTrigger,
|
937
|
+
GoboxAction,
|
938
|
+
GoboxDumper,
|
939
|
+
) = declare_protocol("Gobox")
|
940
|
+
GOBOX_SCHEMA = cv.Schema(
|
941
|
+
{
|
942
|
+
cv.Required(CONF_CODE): cv.int_,
|
943
|
+
}
|
944
|
+
)
|
945
|
+
|
946
|
+
|
947
|
+
@register_binary_sensor("gobox", GoboxBinarySensor, GOBOX_SCHEMA)
|
948
|
+
def gobox_binary_sensor(var, config):
|
949
|
+
cg.add(
|
950
|
+
var.set_data(
|
951
|
+
cg.StructInitializer(
|
952
|
+
GoboxData,
|
953
|
+
("code", config[CONF_CODE]),
|
954
|
+
)
|
955
|
+
)
|
956
|
+
)
|
957
|
+
|
958
|
+
|
959
|
+
@register_trigger("gobox", GoboxTrigger, GoboxData)
|
960
|
+
def gobox_trigger(var, config):
|
961
|
+
pass
|
962
|
+
|
963
|
+
|
964
|
+
@register_dumper("gobox", GoboxDumper)
|
965
|
+
def gobox_dumper(var, config):
|
966
|
+
pass
|
967
|
+
|
968
|
+
|
969
|
+
@register_action("gobox", GoboxAction, GOBOX_SCHEMA)
|
970
|
+
async def gobox_action(var, config, args):
|
971
|
+
template_ = await cg.templatable(config[CONF_CODE], args, cg.int_)
|
972
|
+
cg.add(var.set_code(template_))
|
973
|
+
|
974
|
+
|
884
975
|
# Roomba
|
885
976
|
(
|
886
977
|
RoombaData,
|