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
@@ -7,7 +7,6 @@ from esphome.const import (
|
|
7
7
|
CONF_CLOSE_ACTION,
|
8
8
|
CONF_CLOSE_DURATION,
|
9
9
|
CONF_CLOSE_ENDSTOP,
|
10
|
-
CONF_ID,
|
11
10
|
CONF_MAX_DURATION,
|
12
11
|
CONF_OPEN_ACTION,
|
13
12
|
CONF_OPEN_DURATION,
|
@@ -50,36 +49,43 @@ def validate_infer_endstop(config):
|
|
50
49
|
return config
|
51
50
|
|
52
51
|
|
53
|
-
CONFIG_FEEDBACK_COVER_BASE_SCHEMA =
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
52
|
+
CONFIG_FEEDBACK_COVER_BASE_SCHEMA = (
|
53
|
+
cover.cover_schema(FeedbackCover)
|
54
|
+
.extend(
|
55
|
+
{
|
56
|
+
cv.Required(CONF_STOP_ACTION): automation.validate_automation(single=True),
|
57
|
+
cv.Required(CONF_OPEN_ACTION): automation.validate_automation(single=True),
|
58
|
+
cv.Required(CONF_OPEN_DURATION): cv.positive_time_period_milliseconds,
|
59
|
+
cv.Optional(CONF_OPEN_ENDSTOP): cv.use_id(binary_sensor.BinarySensor),
|
60
|
+
cv.Optional(CONF_OPEN_SENSOR): cv.use_id(binary_sensor.BinarySensor),
|
61
|
+
cv.Optional(CONF_OPEN_OBSTACLE_SENSOR): cv.use_id(
|
62
|
+
binary_sensor.BinarySensor
|
63
|
+
),
|
64
|
+
cv.Required(CONF_CLOSE_ACTION): automation.validate_automation(single=True),
|
65
|
+
cv.Required(CONF_CLOSE_DURATION): cv.positive_time_period_milliseconds,
|
66
|
+
cv.Optional(CONF_CLOSE_ENDSTOP): cv.use_id(binary_sensor.BinarySensor),
|
67
|
+
cv.Optional(CONF_CLOSE_SENSOR): cv.use_id(binary_sensor.BinarySensor),
|
68
|
+
cv.Optional(CONF_CLOSE_OBSTACLE_SENSOR): cv.use_id(
|
69
|
+
binary_sensor.BinarySensor
|
70
|
+
),
|
71
|
+
cv.Optional(CONF_MAX_DURATION): cv.positive_time_period_milliseconds,
|
72
|
+
cv.Optional(CONF_HAS_BUILT_IN_ENDSTOP, default=False): cv.boolean,
|
73
|
+
cv.Optional(CONF_ASSUMED_STATE): cv.boolean,
|
74
|
+
cv.Optional(
|
75
|
+
CONF_UPDATE_INTERVAL, "1000ms"
|
76
|
+
): cv.positive_time_period_milliseconds,
|
77
|
+
cv.Optional(CONF_INFER_ENDSTOP_FROM_MOVEMENT, False): cv.boolean,
|
78
|
+
cv.Optional(
|
79
|
+
CONF_DIRECTION_CHANGE_WAIT_TIME
|
80
|
+
): cv.positive_time_period_milliseconds,
|
81
|
+
cv.Optional(
|
82
|
+
CONF_ACCELERATION_WAIT_TIME, "0s"
|
83
|
+
): cv.positive_time_period_milliseconds,
|
84
|
+
cv.Optional(CONF_OBSTACLE_ROLLBACK, default="10%"): cv.percentage,
|
85
|
+
},
|
86
|
+
)
|
87
|
+
.extend(cv.COMPONENT_SCHEMA)
|
88
|
+
)
|
83
89
|
|
84
90
|
|
85
91
|
CONFIG_SCHEMA = cv.All(
|
@@ -90,9 +96,8 @@ CONFIG_SCHEMA = cv.All(
|
|
90
96
|
|
91
97
|
|
92
98
|
async def to_code(config):
|
93
|
-
var =
|
99
|
+
var = await cover.new_cover(config)
|
94
100
|
await cg.register_component(var, config)
|
95
|
-
await cover.register_cover(var, config)
|
96
101
|
|
97
102
|
# STOP
|
98
103
|
await automation.build_automation(
|
@@ -1,6 +1,7 @@
|
|
1
1
|
#include "feedback_cover.h"
|
2
2
|
#include "esphome/core/hal.h"
|
3
3
|
#include "esphome/core/log.h"
|
4
|
+
#include "esphome/core/application.h"
|
4
5
|
|
5
6
|
namespace esphome {
|
6
7
|
namespace feedback {
|
@@ -220,7 +221,7 @@ void FeedbackCover::set_open_obstacle_sensor(binary_sensor::BinarySensor *open_o
|
|
220
221
|
void FeedbackCover::loop() {
|
221
222
|
if (this->current_operation == COVER_OPERATION_IDLE)
|
222
223
|
return;
|
223
|
-
const uint32_t now =
|
224
|
+
const uint32_t now = App.get_loop_component_start_time();
|
224
225
|
|
225
226
|
// Recompute position every loop cycle
|
226
227
|
this->recompute_position_();
|
@@ -1,7 +1,5 @@
|
|
1
1
|
import esphome.codegen as cg
|
2
2
|
from esphome.components import climate_ir
|
3
|
-
import esphome.config_validation as cv
|
4
|
-
from esphome.const import CONF_ID
|
5
3
|
|
6
4
|
AUTO_LOAD = ["climate_ir"]
|
7
5
|
|
@@ -10,13 +8,8 @@ FujitsuGeneralClimate = fujitsu_general_ns.class_(
|
|
10
8
|
"FujitsuGeneralClimate", climate_ir.ClimateIR
|
11
9
|
)
|
12
10
|
|
13
|
-
CONFIG_SCHEMA = climate_ir.
|
14
|
-
{
|
15
|
-
cv.GenerateID(): cv.declare_id(FujitsuGeneralClimate),
|
16
|
-
}
|
17
|
-
)
|
11
|
+
CONFIG_SCHEMA = climate_ir.climate_ir_with_receiver_schema(FujitsuGeneralClimate)
|
18
12
|
|
19
13
|
|
20
14
|
async def to_code(config):
|
21
|
-
|
22
|
-
await climate_ir.register_climate_ir(var, config)
|
15
|
+
await climate_ir.new_climate_ir(config)
|
@@ -6,6 +6,7 @@
|
|
6
6
|
*/
|
7
7
|
#include "gcja5.h"
|
8
8
|
#include "esphome/core/log.h"
|
9
|
+
#include "esphome/core/application.h"
|
9
10
|
#include <cstring>
|
10
11
|
|
11
12
|
namespace esphome {
|
@@ -16,7 +17,7 @@ static const char *const TAG = "gcja5";
|
|
16
17
|
void GCJA5Component::setup() { ESP_LOGCONFIG(TAG, "Setting up gcja5..."); }
|
17
18
|
|
18
19
|
void GCJA5Component::loop() {
|
19
|
-
const uint32_t now =
|
20
|
+
const uint32_t now = App.get_loop_component_start_time();
|
20
21
|
if (now - this->last_transmission_ >= 500) {
|
21
22
|
// last transmission too long ago. Reset RX index.
|
22
23
|
this->rx_message_.clear();
|
@@ -10,8 +10,10 @@ static const char *const TAG = "gpio.one_wire";
|
|
10
10
|
void GPIOOneWireBus::setup() {
|
11
11
|
ESP_LOGCONFIG(TAG, "Setting up 1-wire bus...");
|
12
12
|
this->t_pin_->setup();
|
13
|
-
// clear bus with 480µs high, otherwise initial reset in search might fail
|
14
13
|
this->t_pin_->pin_mode(gpio::FLAG_INPUT | gpio::FLAG_PULLUP);
|
14
|
+
// clear bus with 480µs high, otherwise initial reset in search might fail
|
15
|
+
this->pin_.digital_write(true);
|
16
|
+
this->pin_.pin_mode(gpio::FLAG_OUTPUT);
|
15
17
|
delayMicroseconds(480);
|
16
18
|
this->search();
|
17
19
|
}
|
@@ -22,40 +24,49 @@ void GPIOOneWireBus::dump_config() {
|
|
22
24
|
this->dump_devices_(TAG);
|
23
25
|
}
|
24
26
|
|
25
|
-
|
27
|
+
int HOT IRAM_ATTR GPIOOneWireBus::reset_int() {
|
28
|
+
InterruptLock lock;
|
26
29
|
// See reset here:
|
27
30
|
// https://www.maximintegrated.com/en/design/technical-documents/app-notes/1/126.html
|
28
31
|
// Wait for communication to clear (delay G)
|
29
|
-
pin_.pin_mode(gpio::FLAG_INPUT | gpio::FLAG_PULLUP);
|
32
|
+
this->pin_.pin_mode(gpio::FLAG_INPUT | gpio::FLAG_PULLUP);
|
30
33
|
uint8_t retries = 125;
|
31
34
|
do {
|
32
35
|
if (--retries == 0)
|
33
|
-
return
|
36
|
+
return -1;
|
34
37
|
delayMicroseconds(2);
|
35
|
-
} while (!pin_.digital_read());
|
38
|
+
} while (!this->pin_.digital_read());
|
36
39
|
|
37
|
-
bool r;
|
40
|
+
bool r = false;
|
38
41
|
|
39
42
|
// Send 480µs LOW TX reset pulse (drive bus low, delay H)
|
40
|
-
pin_.
|
41
|
-
pin_.
|
43
|
+
this->pin_.digital_write(false);
|
44
|
+
this->pin_.pin_mode(gpio::FLAG_OUTPUT);
|
42
45
|
delayMicroseconds(480);
|
43
46
|
|
44
47
|
// Release the bus, delay I
|
45
|
-
pin_.pin_mode(gpio::FLAG_INPUT | gpio::FLAG_PULLUP);
|
46
|
-
|
48
|
+
this->pin_.pin_mode(gpio::FLAG_INPUT | gpio::FLAG_PULLUP);
|
49
|
+
uint32_t start = micros();
|
50
|
+
delayMicroseconds(30);
|
51
|
+
|
52
|
+
while (micros() - start < 300) {
|
53
|
+
// sample bus, 0=device(s) present, 1=no device present
|
54
|
+
r = !this->pin_.digital_read();
|
55
|
+
if (r)
|
56
|
+
break;
|
57
|
+
delayMicroseconds(1);
|
58
|
+
}
|
47
59
|
|
48
|
-
// sample bus, 0=device(s) present, 1=no device present
|
49
|
-
r = !pin_.digital_read();
|
50
60
|
// delay J
|
51
|
-
delayMicroseconds(
|
52
|
-
|
61
|
+
delayMicroseconds(start + 480 - micros());
|
62
|
+
this->pin_.digital_write(true);
|
63
|
+
this->pin_.pin_mode(gpio::FLAG_OUTPUT);
|
64
|
+
return r ? 1 : 0;
|
53
65
|
}
|
54
66
|
|
55
67
|
void HOT IRAM_ATTR GPIOOneWireBus::write_bit_(bool bit) {
|
56
68
|
// drive bus low
|
57
|
-
pin_.
|
58
|
-
pin_.digital_write(false);
|
69
|
+
this->pin_.digital_write(false);
|
59
70
|
|
60
71
|
// from datasheet:
|
61
72
|
// write 0 low time: t_low0: min=60µs, max=120µs
|
@@ -64,72 +75,62 @@ void HOT IRAM_ATTR GPIOOneWireBus::write_bit_(bool bit) {
|
|
64
75
|
// recovery time: t_rec: min=1µs
|
65
76
|
// ds18b20 appears to read the bus after roughly 14µs
|
66
77
|
uint32_t delay0 = bit ? 6 : 60;
|
67
|
-
uint32_t delay1 = bit ?
|
78
|
+
uint32_t delay1 = bit ? 64 : 10;
|
68
79
|
|
69
80
|
// delay A/C
|
70
81
|
delayMicroseconds(delay0);
|
71
82
|
// release bus
|
72
|
-
pin_.digital_write(true);
|
83
|
+
this->pin_.digital_write(true);
|
73
84
|
// delay B/D
|
74
85
|
delayMicroseconds(delay1);
|
75
86
|
}
|
76
87
|
|
77
88
|
bool HOT IRAM_ATTR GPIOOneWireBus::read_bit_() {
|
78
89
|
// drive bus low
|
79
|
-
pin_.
|
80
|
-
pin_.digital_write(false);
|
90
|
+
this->pin_.digital_write(false);
|
81
91
|
|
82
|
-
//
|
83
|
-
|
84
|
-
// we should read at the end of 16µs starting from the bus low
|
85
|
-
// typically, the ds18b20 pulls the line high after 11µs for a logical 1
|
86
|
-
// and 29µs for a logical 0
|
87
|
-
|
88
|
-
uint32_t start = micros();
|
89
|
-
// datasheet says >1µs
|
90
|
-
delayMicroseconds(2);
|
92
|
+
// datasheet says >= 1µs
|
93
|
+
delayMicroseconds(5);
|
91
94
|
|
92
95
|
// release bus, delay E
|
93
|
-
pin_.pin_mode(gpio::FLAG_INPUT | gpio::FLAG_PULLUP);
|
94
|
-
|
95
|
-
// measure from start value directly, to get best accurate timing no matter
|
96
|
-
// how long pin_mode/delayMicroseconds took
|
97
|
-
uint32_t now = micros();
|
98
|
-
if (now - start < 12)
|
99
|
-
delayMicroseconds(12 - (now - start));
|
96
|
+
this->pin_.pin_mode(gpio::FLAG_INPUT | gpio::FLAG_PULLUP);
|
100
97
|
|
98
|
+
delayMicroseconds(8);
|
101
99
|
// sample bus to read bit from peer
|
102
|
-
bool r = pin_.digital_read();
|
100
|
+
bool r = this->pin_.digital_read();
|
103
101
|
|
104
|
-
// read slot is at least 60µs
|
105
|
-
|
106
|
-
if (now - start < 60)
|
107
|
-
delayMicroseconds(60 - (now - start));
|
102
|
+
// read slot is at least 60µs
|
103
|
+
delayMicroseconds(50);
|
108
104
|
|
105
|
+
this->pin_.digital_write(true);
|
106
|
+
this->pin_.pin_mode(gpio::FLAG_OUTPUT);
|
109
107
|
return r;
|
110
108
|
}
|
111
109
|
|
112
110
|
void IRAM_ATTR GPIOOneWireBus::write8(uint8_t val) {
|
111
|
+
InterruptLock lock;
|
113
112
|
for (uint8_t i = 0; i < 8; i++) {
|
114
113
|
this->write_bit_(bool((1u << i) & val));
|
115
114
|
}
|
116
115
|
}
|
117
116
|
|
118
117
|
void IRAM_ATTR GPIOOneWireBus::write64(uint64_t val) {
|
118
|
+
InterruptLock lock;
|
119
119
|
for (uint8_t i = 0; i < 64; i++) {
|
120
120
|
this->write_bit_(bool((1ULL << i) & val));
|
121
121
|
}
|
122
122
|
}
|
123
123
|
|
124
124
|
uint8_t IRAM_ATTR GPIOOneWireBus::read8() {
|
125
|
+
InterruptLock lock;
|
125
126
|
uint8_t ret = 0;
|
126
|
-
for (uint8_t i = 0; i < 8; i++)
|
127
|
+
for (uint8_t i = 0; i < 8; i++)
|
127
128
|
ret |= (uint8_t(this->read_bit_()) << i);
|
128
|
-
}
|
129
129
|
return ret;
|
130
130
|
}
|
131
131
|
|
132
132
|
uint64_t IRAM_ATTR GPIOOneWireBus::read64() {
|
133
|
+
InterruptLock lock;
|
133
134
|
uint64_t ret = 0;
|
134
135
|
for (uint8_t i = 0; i < 8; i++) {
|
135
136
|
ret |= (uint64_t(this->read_bit_()) << i);
|
@@ -144,6 +145,7 @@ void GPIOOneWireBus::reset_search() {
|
|
144
145
|
}
|
145
146
|
|
146
147
|
uint64_t IRAM_ATTR GPIOOneWireBus::search_int() {
|
148
|
+
InterruptLock lock;
|
147
149
|
if (this->last_device_flag_)
|
148
150
|
return 0u;
|
149
151
|
|
@@ -18,7 +18,6 @@ class GPIOOneWireBus : public one_wire::OneWireBus, public Component {
|
|
18
18
|
this->pin_ = pin->to_isr();
|
19
19
|
}
|
20
20
|
|
21
|
-
bool reset() override;
|
22
21
|
void write8(uint8_t val) override;
|
23
22
|
void write64(uint64_t val) override;
|
24
23
|
uint8_t read8() override;
|
@@ -31,10 +30,12 @@ class GPIOOneWireBus : public one_wire::OneWireBus, public Component {
|
|
31
30
|
bool last_device_flag_{false};
|
32
31
|
uint64_t address_;
|
33
32
|
|
33
|
+
int reset_int() override;
|
34
34
|
void reset_search() override;
|
35
35
|
uint64_t search_int() override;
|
36
36
|
void write_bit_(bool bit);
|
37
37
|
bool read_bit_();
|
38
|
+
bool read_bit_(uint32_t *t);
|
38
39
|
};
|
39
40
|
|
40
41
|
} // namespace gpio
|
@@ -8,30 +8,45 @@ namespace esphome {
|
|
8
8
|
namespace gpio_expander {
|
9
9
|
|
10
10
|
/// @brief A class to cache the read state of a GPIO expander.
|
11
|
+
/// This class caches reads between GPIO Pins which are on the same bank.
|
12
|
+
/// This means that for reading whole Port (ex. 8 pins) component needs only one
|
13
|
+
/// I2C/SPI read per main loop call. It assumes, that one bit in byte identifies one GPIO pin
|
14
|
+
/// Template parameters:
|
15
|
+
/// T - Type which represents internal register. Could be uint8_t or uint16_t. Adjust to
|
16
|
+
/// match size of your internal GPIO bank register.
|
17
|
+
/// N - Number of pins
|
11
18
|
template<typename T, T N> class CachedGpioExpander {
|
12
19
|
public:
|
13
20
|
bool digital_read(T pin) {
|
14
|
-
|
15
|
-
|
16
|
-
|
21
|
+
uint8_t bank = pin / (sizeof(T) * BITS_PER_BYTE);
|
22
|
+
if (this->read_cache_invalidated_[bank]) {
|
23
|
+
this->read_cache_invalidated_[bank] = false;
|
24
|
+
if (!this->digital_read_hw(pin))
|
25
|
+
return false;
|
17
26
|
}
|
18
|
-
return this->
|
27
|
+
return this->digital_read_cache(pin);
|
19
28
|
}
|
20
29
|
|
21
30
|
void digital_write(T pin, bool value) { this->digital_write_hw(pin, value); }
|
22
31
|
|
23
32
|
protected:
|
33
|
+
/// @brief Call component low level function to read GPIO state from device
|
24
34
|
virtual bool digital_read_hw(T pin) = 0;
|
35
|
+
/// @brief Call component read function from internal cache.
|
25
36
|
virtual bool digital_read_cache(T pin) = 0;
|
37
|
+
/// @brief Call component low level function to write GPIO state to device
|
26
38
|
virtual void digital_write_hw(T pin, bool value) = 0;
|
39
|
+
const uint8_t cache_byte_size_ = N / (sizeof(T) * BITS_PER_BYTE);
|
27
40
|
|
41
|
+
/// @brief Invalidate cache. This function should be called in component loop().
|
28
42
|
void reset_pin_cache_() {
|
29
|
-
for (T i = 0; i <
|
30
|
-
this->read_cache_invalidated_[i] =
|
43
|
+
for (T i = 0; i < this->cache_byte_size_; i++) {
|
44
|
+
this->read_cache_invalidated_[i] = true;
|
31
45
|
}
|
32
46
|
}
|
33
47
|
|
34
|
-
|
48
|
+
static const uint8_t BITS_PER_BYTE = 8;
|
49
|
+
std::array<bool, N / (sizeof(T) * BITS_PER_BYTE)> read_cache_invalidated_{};
|
35
50
|
};
|
36
51
|
|
37
52
|
} // namespace gpio_expander
|
@@ -9,22 +9,32 @@ from esphome.const import (
|
|
9
9
|
CONF_LONGITUDE,
|
10
10
|
CONF_SATELLITES,
|
11
11
|
CONF_SPEED,
|
12
|
+
DEVICE_CLASS_SPEED,
|
12
13
|
STATE_CLASS_MEASUREMENT,
|
13
14
|
UNIT_DEGREES,
|
14
15
|
UNIT_KILOMETER_PER_HOUR,
|
15
16
|
UNIT_METER,
|
16
17
|
)
|
17
18
|
|
19
|
+
CONF_GPS_ID = "gps_id"
|
20
|
+
CONF_HDOP = "hdop"
|
21
|
+
|
22
|
+
ICON_ALTIMETER = "mdi:altimeter"
|
23
|
+
ICON_COMPASS = "mdi:compass"
|
24
|
+
ICON_LATITUDE = "mdi:latitude"
|
25
|
+
ICON_LONGITUDE = "mdi:longitude"
|
26
|
+
ICON_SATELLITE = "mdi:satellite-variant"
|
27
|
+
ICON_SPEEDOMETER = "mdi:speedometer"
|
28
|
+
|
18
29
|
DEPENDENCIES = ["uart"]
|
19
30
|
AUTO_LOAD = ["sensor"]
|
20
31
|
|
21
|
-
CODEOWNERS = ["@coogle"]
|
32
|
+
CODEOWNERS = ["@coogle", "@ximex"]
|
22
33
|
|
23
34
|
gps_ns = cg.esphome_ns.namespace("gps")
|
24
35
|
GPS = gps_ns.class_("GPS", cg.Component, uart.UARTDevice)
|
25
36
|
GPSListener = gps_ns.class_("GPSListener")
|
26
37
|
|
27
|
-
CONF_GPS_ID = "gps_id"
|
28
38
|
MULTI_CONF = True
|
29
39
|
CONFIG_SCHEMA = cv.All(
|
30
40
|
cv.Schema(
|
@@ -32,28 +42,44 @@ CONFIG_SCHEMA = cv.All(
|
|
32
42
|
cv.GenerateID(): cv.declare_id(GPS),
|
33
43
|
cv.Optional(CONF_LATITUDE): sensor.sensor_schema(
|
34
44
|
unit_of_measurement=UNIT_DEGREES,
|
45
|
+
icon=ICON_LATITUDE,
|
35
46
|
accuracy_decimals=6,
|
47
|
+
state_class=STATE_CLASS_MEASUREMENT,
|
36
48
|
),
|
37
49
|
cv.Optional(CONF_LONGITUDE): sensor.sensor_schema(
|
38
50
|
unit_of_measurement=UNIT_DEGREES,
|
51
|
+
icon=ICON_LONGITUDE,
|
39
52
|
accuracy_decimals=6,
|
53
|
+
state_class=STATE_CLASS_MEASUREMENT,
|
40
54
|
),
|
41
55
|
cv.Optional(CONF_SPEED): sensor.sensor_schema(
|
42
56
|
unit_of_measurement=UNIT_KILOMETER_PER_HOUR,
|
43
|
-
|
57
|
+
icon=ICON_SPEEDOMETER,
|
58
|
+
accuracy_decimals=3,
|
59
|
+
device_class=DEVICE_CLASS_SPEED,
|
60
|
+
state_class=STATE_CLASS_MEASUREMENT,
|
44
61
|
),
|
45
62
|
cv.Optional(CONF_COURSE): sensor.sensor_schema(
|
46
63
|
unit_of_measurement=UNIT_DEGREES,
|
64
|
+
icon=ICON_COMPASS,
|
47
65
|
accuracy_decimals=2,
|
66
|
+
state_class=STATE_CLASS_MEASUREMENT,
|
48
67
|
),
|
49
68
|
cv.Optional(CONF_ALTITUDE): sensor.sensor_schema(
|
50
69
|
unit_of_measurement=UNIT_METER,
|
51
|
-
|
70
|
+
icon=ICON_ALTIMETER,
|
71
|
+
accuracy_decimals=2,
|
72
|
+
state_class=STATE_CLASS_MEASUREMENT,
|
52
73
|
),
|
53
74
|
cv.Optional(CONF_SATELLITES): sensor.sensor_schema(
|
75
|
+
icon=ICON_SATELLITE,
|
54
76
|
accuracy_decimals=0,
|
55
77
|
state_class=STATE_CLASS_MEASUREMENT,
|
56
78
|
),
|
79
|
+
cv.Optional(CONF_HDOP): sensor.sensor_schema(
|
80
|
+
accuracy_decimals=3,
|
81
|
+
state_class=STATE_CLASS_MEASUREMENT,
|
82
|
+
),
|
57
83
|
}
|
58
84
|
)
|
59
85
|
.extend(cv.polling_component_schema("20s"))
|
@@ -68,29 +94,33 @@ async def to_code(config):
|
|
68
94
|
await cg.register_component(var, config)
|
69
95
|
await uart.register_uart_device(var, config)
|
70
96
|
|
71
|
-
if
|
72
|
-
sens = await sensor.new_sensor(
|
97
|
+
if latitude_config := config.get(CONF_LATITUDE):
|
98
|
+
sens = await sensor.new_sensor(latitude_config)
|
73
99
|
cg.add(var.set_latitude_sensor(sens))
|
74
100
|
|
75
|
-
if
|
76
|
-
sens = await sensor.new_sensor(
|
101
|
+
if longitude_config := config.get(CONF_LONGITUDE):
|
102
|
+
sens = await sensor.new_sensor(longitude_config)
|
77
103
|
cg.add(var.set_longitude_sensor(sens))
|
78
104
|
|
79
|
-
if
|
80
|
-
sens = await sensor.new_sensor(
|
105
|
+
if speed_config := config.get(CONF_SPEED):
|
106
|
+
sens = await sensor.new_sensor(speed_config)
|
81
107
|
cg.add(var.set_speed_sensor(sens))
|
82
108
|
|
83
|
-
if
|
84
|
-
sens = await sensor.new_sensor(
|
109
|
+
if course_config := config.get(CONF_COURSE):
|
110
|
+
sens = await sensor.new_sensor(course_config)
|
85
111
|
cg.add(var.set_course_sensor(sens))
|
86
112
|
|
87
|
-
if
|
88
|
-
sens = await sensor.new_sensor(
|
113
|
+
if altitude_config := config.get(CONF_ALTITUDE):
|
114
|
+
sens = await sensor.new_sensor(altitude_config)
|
89
115
|
cg.add(var.set_altitude_sensor(sens))
|
90
116
|
|
91
|
-
if
|
92
|
-
sens = await sensor.new_sensor(
|
117
|
+
if satellites_config := config.get(CONF_SATELLITES):
|
118
|
+
sens = await sensor.new_sensor(satellites_config)
|
93
119
|
cg.add(var.set_satellites_sensor(sens))
|
94
120
|
|
121
|
+
if hdop_config := config.get(CONF_HDOP):
|
122
|
+
sens = await sensor.new_sensor(hdop_config)
|
123
|
+
cg.add(var.set_hdop_sensor(sens))
|
124
|
+
|
95
125
|
# https://platformio.org/lib/show/1655/TinyGPSPlus
|
96
|
-
cg.add_library("mikalhart/TinyGPSPlus", "1.0
|
126
|
+
cg.add_library("mikalhart/TinyGPSPlus", "1.1.0")
|
esphome/components/gps/gps.cpp
CHANGED
@@ -10,6 +10,17 @@ static const char *const TAG = "gps";
|
|
10
10
|
|
11
11
|
TinyGPSPlus &GPSListener::get_tiny_gps() { return this->parent_->get_tiny_gps(); }
|
12
12
|
|
13
|
+
void GPS::dump_config() {
|
14
|
+
ESP_LOGCONFIG(TAG, "GPS:");
|
15
|
+
LOG_SENSOR(" ", "Latitude", this->latitude_sensor_);
|
16
|
+
LOG_SENSOR(" ", "Longitude", this->longitude_sensor_);
|
17
|
+
LOG_SENSOR(" ", "Speed", this->speed_sensor_);
|
18
|
+
LOG_SENSOR(" ", "Course", this->course_sensor_);
|
19
|
+
LOG_SENSOR(" ", "Altitude", this->altitude_sensor_);
|
20
|
+
LOG_SENSOR(" ", "Satellites", this->satellites_sensor_);
|
21
|
+
LOG_SENSOR(" ", "HDOP", this->hdop_sensor_);
|
22
|
+
}
|
23
|
+
|
13
24
|
void GPS::update() {
|
14
25
|
if (this->latitude_sensor_ != nullptr)
|
15
26
|
this->latitude_sensor_->publish_state(this->latitude_);
|
@@ -28,43 +39,51 @@ void GPS::update() {
|
|
28
39
|
|
29
40
|
if (this->satellites_sensor_ != nullptr)
|
30
41
|
this->satellites_sensor_->publish_state(this->satellites_);
|
42
|
+
|
43
|
+
if (this->hdop_sensor_ != nullptr)
|
44
|
+
this->hdop_sensor_->publish_state(this->hdop_);
|
31
45
|
}
|
32
46
|
|
33
47
|
void GPS::loop() {
|
34
|
-
while (this->available() && !this->has_time_) {
|
48
|
+
while (this->available() > 0 && !this->has_time_) {
|
35
49
|
if (this->tiny_gps_.encode(this->read())) {
|
36
|
-
if (tiny_gps_.location.isUpdated()) {
|
37
|
-
this->latitude_ = tiny_gps_.location.lat();
|
38
|
-
this->longitude_ = tiny_gps_.location.lng();
|
50
|
+
if (this->tiny_gps_.location.isUpdated()) {
|
51
|
+
this->latitude_ = this->tiny_gps_.location.lat();
|
52
|
+
this->longitude_ = this->tiny_gps_.location.lng();
|
39
53
|
|
40
54
|
ESP_LOGD(TAG, "Location:");
|
41
|
-
ESP_LOGD(TAG, " Lat:
|
42
|
-
ESP_LOGD(TAG, " Lon:
|
55
|
+
ESP_LOGD(TAG, " Lat: %.6f °", this->latitude_);
|
56
|
+
ESP_LOGD(TAG, " Lon: %.6f °", this->longitude_);
|
43
57
|
}
|
44
58
|
|
45
|
-
if (tiny_gps_.speed.isUpdated()) {
|
46
|
-
this->speed_ = tiny_gps_.speed.kmph();
|
47
|
-
ESP_LOGD(TAG, "Speed:");
|
48
|
-
ESP_LOGD(TAG, " %f km/h", this->speed_);
|
59
|
+
if (this->tiny_gps_.speed.isUpdated()) {
|
60
|
+
this->speed_ = this->tiny_gps_.speed.kmph();
|
61
|
+
ESP_LOGD(TAG, "Speed: %.3f km/h", this->speed_);
|
49
62
|
}
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
ESP_LOGD(TAG, "
|
63
|
+
|
64
|
+
if (this->tiny_gps_.course.isUpdated()) {
|
65
|
+
this->course_ = this->tiny_gps_.course.deg();
|
66
|
+
ESP_LOGD(TAG, "Course: %.2f °", this->course_);
|
54
67
|
}
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
ESP_LOGD(TAG, "
|
68
|
+
|
69
|
+
if (this->tiny_gps_.altitude.isUpdated()) {
|
70
|
+
this->altitude_ = this->tiny_gps_.altitude.meters();
|
71
|
+
ESP_LOGD(TAG, "Altitude: %.2f m", this->altitude_);
|
59
72
|
}
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
ESP_LOGD(TAG, "
|
73
|
+
|
74
|
+
if (this->tiny_gps_.satellites.isUpdated()) {
|
75
|
+
this->satellites_ = this->tiny_gps_.satellites.value();
|
76
|
+
ESP_LOGD(TAG, "Satellites: %d", this->satellites_);
|
77
|
+
}
|
78
|
+
|
79
|
+
if (this->tiny_gps_.hdop.isUpdated()) {
|
80
|
+
this->hdop_ = this->tiny_gps_.hdop.hdop();
|
81
|
+
ESP_LOGD(TAG, "HDOP: %.3f", this->hdop_);
|
64
82
|
}
|
65
83
|
|
66
|
-
for (auto *listener : this->listeners_)
|
84
|
+
for (auto *listener : this->listeners_) {
|
67
85
|
listener->on_update(this->tiny_gps_);
|
86
|
+
}
|
68
87
|
}
|
69
88
|
}
|
70
89
|
}
|