esphome 2025.4.2__py3-none-any.whl → 2025.5.0b3__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 +81 -13
- esphome/components/api/api_connection.h +13 -1
- esphome/components/api/api_frame_helper.cpp +232 -177
- esphome/components/api/api_frame_helper.h +61 -8
- esphome/components/api/api_noise_context.h +13 -4
- esphome/components/api/api_pb2.cpp +1422 -1
- esphome/components/api/api_pb2.h +255 -1
- esphome/components/api/api_pb2_service.cpp +162 -49
- esphome/components/api/api_pb2_service.h +90 -51
- esphome/components/api/api_pb2_size.h +361 -0
- esphome/components/api/api_server.cpp +110 -34
- esphome/components/api/api_server.h +8 -0
- esphome/components/api/proto.h +86 -17
- esphome/components/as7341/as7341.h +1 -1
- esphome/components/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 +6 -0
- esphome/components/debug/debug_esp32.cpp +109 -254
- esphome/components/debug/sensor.py +14 -0
- esphome/components/deep_sleep/deep_sleep_esp32.cpp +13 -1
- esphome/components/delonghi/climate.py +2 -9
- esphome/components/demo/__init__.py +18 -20
- esphome/components/dfrobot_sen0395/switch/__init__.py +21 -22
- esphome/components/dps310/sensor.py +6 -6
- esphome/components/ee895/sensor.py +9 -9
- esphome/components/emmeti/climate.py +2 -9
- esphome/components/endstop/cover.py +17 -16
- esphome/components/endstop/endstop_cover.cpp +2 -1
- esphome/components/ens160_base/__init__.py +12 -9
- esphome/components/esp32/__init__.py +60 -3
- esphome/components/esp32/core.cpp +11 -5
- esphome/components/esp32/gpio.cpp +86 -24
- esphome/components/esp32/gpio.py +15 -16
- esphome/components/esp32/gpio_esp32.py +1 -2
- esphome/components/esp32/gpio_esp32_c2.py +1 -1
- esphome/components/esp32/gpio_esp32_c3.py +1 -1
- esphome/components/esp32/gpio_esp32_c6.py +1 -1
- esphome/components/esp32/gpio_esp32_h2.py +1 -1
- esphome/components/esp32_ble/ble.cpp +1 -0
- esphome/components/esp32_ble/ble.h +5 -3
- esphome/components/esp32_ble/ble_advertising.cpp +2 -1
- esphome/components/esp32_ble/ble_advertising.h +1 -0
- esphome/components/esp32_ble_server/__init__.py +3 -0
- esphome/components/esp32_ble_tracker/__init__.py +7 -1
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +192 -118
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +29 -3
- esphome/components/esp32_camera/esp32_camera.cpp +2 -1
- esphome/components/esp32_camera/esp32_camera.h +1 -1
- esphome/components/esp32_can/esp32_can.cpp +1 -1
- esphome/components/esp32_improv/esp32_improv_component.cpp +1 -1
- esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
- esphome/components/esp32_rmt_led_strip/led_strip.h +7 -5
- esphome/components/esp32_rmt_led_strip/light.py +9 -1
- esphome/components/esp32_touch/esp32_touch.cpp +1 -1
- esphome/components/esp8266/gpio.cpp +69 -8
- esphome/components/ethernet/ethernet_component.cpp +1 -1
- esphome/components/event/__init__.py +13 -10
- esphome/components/factory_reset/switch/__init__.py +7 -21
- esphome/components/fan/__init__.py +52 -5
- esphome/components/fastled_base/__init__.py +1 -4
- esphome/components/fastled_base/fastled_light.cpp +1 -1
- esphome/components/feedback/cover.py +38 -33
- esphome/components/feedback/feedback_cover.cpp +2 -1
- esphome/components/fujitsu_general/climate.py +2 -9
- esphome/components/gcja5/gcja5.cpp +2 -1
- esphome/components/gpio/one_wire/gpio_one_wire.cpp +45 -43
- esphome/components/gpio/one_wire/gpio_one_wire.h +2 -1
- esphome/components/gpio_expander/cached_gpio.h +22 -7
- esphome/components/gps/__init__.py +47 -17
- esphome/components/gps/gps.cpp +42 -23
- esphome/components/gps/gps.h +17 -13
- esphome/components/graph/__init__.py +1 -2
- esphome/components/gree/climate.py +4 -6
- esphome/components/gree/gree.cpp +16 -2
- esphome/components/gree/gree.h +2 -2
- esphome/components/growatt_solar/growatt_solar.cpp +2 -1
- esphome/components/haier/climate.py +37 -34
- esphome/components/hbridge/fan/__init__.py +19 -17
- esphome/components/he60r/cover.py +4 -5
- esphome/components/heatpumpir/climate.py +3 -6
- esphome/components/hitachi_ac344/climate.py +2 -9
- esphome/components/hitachi_ac424/climate.py +2 -9
- esphome/components/hm3301/hm3301.h +1 -1
- esphome/components/hte501/sensor.py +6 -6
- esphome/components/http_request/__init__.py +39 -6
- esphome/components/http_request/http_request.cpp +20 -0
- esphome/components/http_request/http_request.h +57 -15
- esphome/components/http_request/http_request_arduino.cpp +22 -6
- esphome/components/http_request/http_request_arduino.h +4 -3
- esphome/components/http_request/http_request_host.cpp +141 -0
- esphome/components/http_request/http_request_host.h +37 -0
- esphome/components/http_request/http_request_idf.cpp +35 -3
- esphome/components/http_request/http_request_idf.h +10 -3
- esphome/components/http_request/httplib.h +9691 -0
- esphome/components/http_request/update/__init__.py +11 -8
- esphome/components/hyt271/sensor.py +6 -6
- esphome/components/i2c/i2c.h +4 -0
- esphome/components/i2c/i2c_bus_esp_idf.cpp +1 -1
- esphome/components/i2s_audio/__init__.py +131 -22
- esphome/components/i2s_audio/i2s_audio.h +44 -4
- esphome/components/i2s_audio/media_player/__init__.py +19 -9
- esphome/components/i2s_audio/microphone/__init__.py +63 -5
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +351 -61
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +40 -6
- esphome/components/i2s_audio/speaker/__init__.py +31 -5
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +155 -19
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +17 -4
- esphome/components/ili9xxx/ili9xxx_init.h +1 -1
- esphome/components/image/__init__.py +37 -17
- esphome/components/image/image.cpp +25 -8
- esphome/components/internal_temperature/internal_temperature.cpp +6 -4
- esphome/components/key_collector/__init__.py +35 -0
- esphome/components/key_collector/key_collector.cpp +8 -0
- esphome/components/key_collector/key_collector.h +10 -0
- esphome/components/kuntze/kuntze.cpp +2 -1
- esphome/components/ld2410/ld2410.h +1 -1
- esphome/components/ld2450/ld2450.h +1 -1
- esphome/components/light/__init__.py +57 -0
- esphome/components/lock/__init__.py +51 -4
- esphome/components/lock/automation.h +2 -13
- esphome/components/logger/__init__.py +22 -0
- esphome/components/logger/logger.cpp +154 -103
- esphome/components/logger/logger.h +211 -36
- esphome/components/logger/task_log_buffer.cpp +138 -0
- esphome/components/logger/task_log_buffer.h +69 -0
- esphome/components/lvgl/__init__.py +13 -5
- esphome/components/lvgl/automation.py +50 -1
- esphome/components/lvgl/defines.py +0 -1
- esphome/components/lvgl/lvgl_esphome.cpp +5 -1
- esphome/components/lvgl/text/__init__.py +1 -2
- esphome/components/mapping/__init__.py +134 -0
- esphome/components/matrix_keypad/matrix_keypad.cpp +2 -1
- esphome/components/max7219digit/max7219digit.cpp +28 -27
- esphome/components/mdns/__init__.py +11 -5
- esphome/components/mdns/mdns_component.cpp +11 -5
- esphome/components/mdns/mdns_component.h +3 -2
- esphome/components/mdns/mdns_esp32.cpp +4 -3
- esphome/components/mdns/mdns_esp8266.cpp +4 -2
- esphome/components/mdns/mdns_libretiny.cpp +4 -2
- esphome/components/mdns/mdns_rp2040.cpp +4 -2
- esphome/components/media_player/__init__.py +33 -1
- esphome/components/mhz19/sensor.py +11 -7
- esphome/components/micro_wake_word/__init__.py +99 -31
- esphome/components/micro_wake_word/automation.h +54 -0
- esphome/components/micro_wake_word/micro_wake_word.cpp +331 -319
- esphome/components/micro_wake_word/micro_wake_word.h +58 -105
- esphome/components/micro_wake_word/preprocessor_settings.h +19 -2
- esphome/components/micro_wake_word/streaming_model.cpp +158 -41
- esphome/components/micro_wake_word/streaming_model.h +85 -13
- esphome/components/microphone/__init__.py +139 -9
- esphome/components/microphone/automation.h +14 -2
- esphome/components/microphone/microphone.cpp +21 -0
- esphome/components/microphone/microphone.h +14 -5
- esphome/components/microphone/microphone_source.cpp +95 -0
- esphome/components/microphone/microphone_source.h +80 -0
- esphome/components/mics_4514/sensor.py +25 -14
- esphome/components/midea/climate.py +3 -4
- esphome/components/midea_ir/climate.py +3 -5
- esphome/components/mipi_spi/__init__.py +15 -0
- esphome/components/mipi_spi/display.py +474 -0
- esphome/components/mipi_spi/mipi_spi.cpp +481 -0
- esphome/components/mipi_spi/mipi_spi.h +171 -0
- esphome/components/mipi_spi/models/__init__.py +65 -0
- esphome/components/mipi_spi/models/amoled.py +72 -0
- esphome/components/mipi_spi/models/commands.py +82 -0
- esphome/components/mipi_spi/models/cyd.py +10 -0
- esphome/components/mipi_spi/models/ili.py +749 -0
- esphome/components/mipi_spi/models/jc.py +260 -0
- esphome/components/mipi_spi/models/lanbon.py +15 -0
- esphome/components/mipi_spi/models/lilygo.py +60 -0
- esphome/components/mipi_spi/models/waveshare.py +139 -0
- esphome/components/mitsubishi/climate.py +2 -5
- esphome/components/mitsubishi/mitsubishi.cpp +9 -9
- esphome/components/mixer/speaker/mixer_speaker.cpp +12 -22
- esphome/components/mixer/speaker/mixer_speaker.h +1 -3
- esphome/components/mlx90393/sensor.py +5 -0
- esphome/components/mlx90393/sensor_mlx90393.cpp +195 -13
- esphome/components/mlx90393/sensor_mlx90393.h +21 -4
- esphome/components/modbus/modbus.cpp +2 -1
- esphome/components/mqtt/__init__.py +1 -1
- esphome/components/mqtt/mqtt_client.cpp +6 -2
- esphome/components/mqtt/mqtt_const.h +4 -0
- esphome/components/mqtt/mqtt_fan.cpp +39 -0
- esphome/components/mqtt/mqtt_fan.h +2 -0
- esphome/components/ms5611/sensor.py +6 -6
- esphome/components/ms8607/sensor.py +3 -3
- esphome/components/network/__init__.py +1 -1
- esphome/components/nextion/base_component.py +17 -16
- esphome/components/nextion/display.py +11 -2
- esphome/components/nextion/nextion.cpp +39 -1
- esphome/components/nextion/nextion.h +50 -0
- esphome/components/noblex/climate.py +2 -9
- esphome/components/number/__init__.py +12 -9
- esphome/components/one_wire/one_wire_bus.cpp +14 -10
- esphome/components/one_wire/one_wire_bus.h +14 -8
- esphome/components/online_image/bmp_image.cpp +48 -11
- esphome/components/online_image/bmp_image.h +2 -0
- esphome/components/opentherm/binary_sensor/__init__.py +2 -4
- esphome/components/opentherm/number/__init__.py +11 -20
- esphome/components/opentherm/sensor/__init__.py +3 -3
- esphome/components/opentherm/switch/__init__.py +3 -5
- esphome/components/output/lock/__init__.py +11 -9
- esphome/components/packages/__init__.py +33 -31
- esphome/components/packet_transport/__init__.py +201 -0
- esphome/components/packet_transport/binary_sensor.py +19 -0
- esphome/components/packet_transport/packet_transport.cpp +534 -0
- esphome/components/packet_transport/packet_transport.h +154 -0
- esphome/components/packet_transport/sensor.py +19 -0
- esphome/components/pca9685/pca9685_output.cpp +2 -1
- esphome/components/pid/climate.py +2 -4
- esphome/components/pm2005/__init__.py +1 -0
- esphome/components/pm2005/pm2005.cpp +123 -0
- esphome/components/pm2005/pm2005.h +46 -0
- esphome/components/pm2005/sensor.py +86 -0
- esphome/components/pmsa003i/pmsa003i.cpp +43 -16
- esphome/components/pmsa003i/pmsa003i.h +25 -25
- esphome/components/pmsx003/pmsx003.cpp +195 -230
- esphome/components/pmsx003/pmsx003.h +51 -33
- esphome/components/pmsx003/sensor.py +21 -11
- esphome/components/pn7150/pn7150.h +2 -2
- esphome/components/pn7160/pn7160.h +2 -2
- esphome/components/prometheus/prometheus_handler.cpp +174 -0
- esphome/components/prometheus/prometheus_handler.h +17 -0
- esphome/components/psram/__init__.py +7 -5
- esphome/components/pulse_meter/pulse_meter_sensor.cpp +32 -12
- esphome/components/pulse_meter/pulse_meter_sensor.h +5 -5
- esphome/components/pzem004t/pzem004t.cpp +2 -1
- esphome/components/qspi_dbi/__init__.py +0 -1
- esphome/components/qspi_dbi/display.py +2 -1
- esphome/components/qspi_dbi/models.py +1 -2
- esphome/components/remote_base/__init__.py +91 -0
- esphome/components/remote_base/beo4_protocol.cpp +153 -0
- esphome/components/remote_base/beo4_protocol.h +43 -0
- esphome/components/remote_base/gobox_protocol.cpp +131 -0
- esphome/components/remote_base/gobox_protocol.h +54 -0
- esphome/components/remote_receiver/remote_receiver_esp32.cpp +16 -9
- esphome/components/resampler/speaker/resampler_speaker.cpp +12 -10
- esphome/components/resampler/speaker/resampler_speaker.h +1 -1
- esphome/components/rf_bridge/rf_bridge.cpp +2 -1
- esphome/components/scd30/sensor.py +2 -3
- esphome/components/scd4x/sensor.py +4 -5
- esphome/components/sdp3x/sensor.py +2 -1
- esphome/components/sds011/sds011.cpp +2 -1
- esphome/components/select/__init__.py +19 -20
- esphome/components/sen5x/sen5x.cpp +55 -36
- esphome/components/sen5x/sensor.py +1 -1
- esphome/components/senseair/sensor.py +3 -3
- esphome/components/sensor/__init__.py +158 -14
- esphome/components/sensor/filter.cpp +23 -0
- esphome/components/sensor/filter.h +22 -0
- esphome/components/sgp30/sensor.py +14 -16
- esphome/components/sgp4x/sensor.py +1 -1
- esphome/components/sht4x/sht4x.cpp +43 -22
- esphome/components/sht4x/sht4x.h +1 -1
- esphome/components/shtcx/sensor.py +6 -6
- esphome/components/slow_pwm/slow_pwm_output.cpp +2 -1
- esphome/components/sml/text_sensor/__init__.py +4 -6
- esphome/components/sound_level/__init__.py +0 -0
- esphome/components/sound_level/sensor.py +97 -0
- esphome/components/sound_level/sound_level.cpp +194 -0
- esphome/components/sound_level/sound_level.h +73 -0
- esphome/components/speaker/media_player/__init__.py +4 -8
- esphome/components/speaker/media_player/speaker_media_player.cpp +0 -18
- esphome/components/speaker/media_player/speaker_media_player.h +0 -11
- esphome/components/speaker/speaker.h +4 -7
- esphome/components/speed/fan/__init__.py +17 -16
- esphome/components/spi/spi.h +11 -1
- esphome/components/sprinkler/__init__.py +18 -19
- esphome/components/sprinkler/sprinkler.cpp +6 -5
- esphome/components/switch/__init__.py +32 -42
- esphome/components/syslog/__init__.py +41 -0
- esphome/components/syslog/esphome_syslog.cpp +49 -0
- esphome/components/syslog/esphome_syslog.h +27 -0
- esphome/components/t6615/sensor.py +3 -3
- esphome/components/t6615/t6615.cpp +2 -1
- esphome/components/tca9555/tca9555.cpp +11 -6
- esphome/components/tcl112/climate.py +2 -9
- esphome/components/template/alarm_control_panel/__init__.py +7 -6
- esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +21 -17
- esphome/components/template/alarm_control_panel/template_alarm_control_panel.h +2 -1
- esphome/components/template/cover/__init__.py +27 -21
- esphome/components/template/fan/__init__.py +14 -12
- esphome/components/template/lock/__init__.py +20 -25
- esphome/components/template/lock/automation.h +18 -0
- esphome/components/template/text/__init__.py +4 -3
- esphome/components/template/valve/__init__.py +32 -21
- esphome/components/template/valve/automation.h +24 -0
- esphome/components/text/__init__.py +32 -1
- esphome/components/text_sensor/__init__.py +24 -29
- esphome/components/thermostat/climate.py +5 -5
- esphome/components/time_based/cover.py +17 -16
- esphome/components/time_based/time_based_cover.cpp +2 -1
- esphome/components/tm1638/switch/__init__.py +10 -7
- esphome/components/tormatic/cover.py +4 -5
- esphome/components/toshiba/climate.py +3 -5
- esphome/components/touchscreen/touchscreen.cpp +3 -1
- esphome/components/tuya/climate/__init__.py +5 -6
- esphome/components/tuya/cover/__init__.py +6 -11
- esphome/components/tuya/select/__init__.py +15 -5
- esphome/components/tuya/select/tuya_select.cpp +6 -1
- esphome/components/tuya/select/tuya_select.h +5 -1
- esphome/components/uart/packet_transport/__init__.py +20 -0
- esphome/components/uart/packet_transport/uart_transport.cpp +88 -0
- esphome/components/uart/packet_transport/uart_transport.h +41 -0
- esphome/components/uart/switch/uart_switch.cpp +2 -1
- esphome/components/udp/__init__.py +126 -128
- esphome/components/udp/automation.h +40 -0
- esphome/components/udp/binary_sensor.py +3 -25
- esphome/components/udp/packet_transport/__init__.py +29 -0
- esphome/components/udp/packet_transport/udp_transport.cpp +36 -0
- esphome/components/udp/packet_transport/udp_transport.h +28 -0
- esphome/components/udp/sensor.py +3 -25
- esphome/components/udp/udp_component.cpp +26 -470
- esphome/components/udp/udp_component.h +21 -128
- esphome/components/update/__init__.py +31 -1
- esphome/components/uponor_smatrix/climate/__init__.py +4 -9
- esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +2 -1
- esphome/components/uponor_smatrix/uponor_smatrix.cpp +2 -1
- esphome/components/uptime/text_sensor/__init__.py +47 -7
- esphome/components/uptime/text_sensor/uptime_text_sensor.cpp +12 -7
- esphome/components/uptime/text_sensor/uptime_text_sensor.h +19 -0
- esphome/components/valve/__init__.py +34 -3
- esphome/components/valve/automation.h +1 -19
- esphome/components/vl53l0x/sensor.py +11 -0
- esphome/components/vl53l0x/vl53l0x_sensor.cpp +5 -1
- esphome/components/vl53l0x/vl53l0x_sensor.h +2 -1
- esphome/components/voice_assistant/__init__.py +36 -10
- esphome/components/voice_assistant/voice_assistant.cpp +170 -144
- esphome/components/voice_assistant/voice_assistant.h +26 -25
- esphome/components/waveshare_epaper/display.py +6 -0
- esphome/components/waveshare_epaper/waveshare_epaper.cpp +439 -37
- esphome/components/waveshare_epaper/waveshare_epaper.h +60 -11
- esphome/components/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 +23 -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/macros.h +4 -0
- esphome/core/scheduler.cpp +7 -1
- esphome/cpp_generator.py +6 -2
- esphome/dashboard/web_server.py +3 -3
- esphome/helpers.py +39 -0
- esphome/loader.py +4 -0
- esphome/log.py +15 -19
- esphome/mqtt.py +23 -10
- esphome/platformio_api.py +1 -1
- esphome/schema_extractors.py +0 -1
- esphome/voluptuous_schema.py +3 -1
- esphome/vscode.py +15 -0
- esphome/wizard.py +47 -37
- esphome/zeroconf.py +7 -3
- {esphome-2025.4.2.dist-info → esphome-2025.5.0b3.dist-info}/METADATA +10 -11
- {esphome-2025.4.2.dist-info → esphome-2025.5.0b3.dist-info}/RECORD +440 -380
- {esphome-2025.4.2.dist-info → esphome-2025.5.0b3.dist-info}/WHEEL +1 -1
- {esphome-2025.4.2.dist-info → esphome-2025.5.0b3.dist-info}/entry_points.txt +0 -0
- {esphome-2025.4.2.dist-info → esphome-2025.5.0b3.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.4.2.dist-info → esphome-2025.5.0b3.dist-info}/top_level.txt +0 -0
@@ -6,13 +6,41 @@ namespace mlx90393 {
|
|
6
6
|
|
7
7
|
static const char *const TAG = "mlx90393";
|
8
8
|
|
9
|
+
const LogString *settings_to_string(MLX90393Setting setting) {
|
10
|
+
switch (setting) {
|
11
|
+
case MLX90393_GAIN_SEL:
|
12
|
+
return LOG_STR("gain");
|
13
|
+
case MLX90393_RESOLUTION:
|
14
|
+
return LOG_STR("resolution");
|
15
|
+
case MLX90393_OVER_SAMPLING:
|
16
|
+
return LOG_STR("oversampling");
|
17
|
+
case MLX90393_DIGITAL_FILTERING:
|
18
|
+
return LOG_STR("digital filtering");
|
19
|
+
case MLX90393_TEMPERATURE_OVER_SAMPLING:
|
20
|
+
return LOG_STR("temperature oversampling");
|
21
|
+
case MLX90393_TEMPERATURE_COMPENSATION:
|
22
|
+
return LOG_STR("temperature compensation");
|
23
|
+
case MLX90393_HALLCONF:
|
24
|
+
return LOG_STR("hallconf");
|
25
|
+
case MLX90393_LAST:
|
26
|
+
return LOG_STR("error");
|
27
|
+
default:
|
28
|
+
return LOG_STR("unknown");
|
29
|
+
}
|
30
|
+
};
|
31
|
+
|
9
32
|
bool MLX90393Cls::transceive(const uint8_t *request, size_t request_size, uint8_t *response, size_t response_size) {
|
10
33
|
i2c::ErrorCode e = this->write(request, request_size);
|
11
34
|
if (e != i2c::ErrorCode::ERROR_OK) {
|
35
|
+
ESP_LOGV(TAG, "i2c failed to write %u", e);
|
12
36
|
return false;
|
13
37
|
}
|
14
38
|
e = this->read(response, response_size);
|
15
|
-
|
39
|
+
if (e != i2c::ErrorCode::ERROR_OK) {
|
40
|
+
ESP_LOGV(TAG, "i2c failed to read %u", e);
|
41
|
+
return false;
|
42
|
+
}
|
43
|
+
return true;
|
16
44
|
}
|
17
45
|
|
18
46
|
bool MLX90393Cls::has_drdy_pin() { return this->drdy_pin_ != nullptr; }
|
@@ -27,6 +55,53 @@ bool MLX90393Cls::read_drdy_pin() {
|
|
27
55
|
void MLX90393Cls::sleep_millis(uint32_t millis) { delay(millis); }
|
28
56
|
void MLX90393Cls::sleep_micros(uint32_t micros) { delayMicroseconds(micros); }
|
29
57
|
|
58
|
+
uint8_t MLX90393Cls::apply_setting_(MLX90393Setting which) {
|
59
|
+
uint8_t ret = -1;
|
60
|
+
switch (which) {
|
61
|
+
case MLX90393_GAIN_SEL:
|
62
|
+
ret = this->mlx_.setGainSel(this->gain_);
|
63
|
+
break;
|
64
|
+
case MLX90393_RESOLUTION:
|
65
|
+
ret = this->mlx_.setResolution(this->resolutions_[0], this->resolutions_[1], this->resolutions_[2]);
|
66
|
+
break;
|
67
|
+
case MLX90393_OVER_SAMPLING:
|
68
|
+
ret = this->mlx_.setOverSampling(this->oversampling_);
|
69
|
+
break;
|
70
|
+
case MLX90393_DIGITAL_FILTERING:
|
71
|
+
ret = this->mlx_.setDigitalFiltering(this->filter_);
|
72
|
+
break;
|
73
|
+
case MLX90393_TEMPERATURE_OVER_SAMPLING:
|
74
|
+
ret = this->mlx_.setTemperatureOverSampling(this->temperature_oversampling_);
|
75
|
+
break;
|
76
|
+
case MLX90393_TEMPERATURE_COMPENSATION:
|
77
|
+
ret = this->mlx_.setTemperatureCompensation(this->temperature_compensation_);
|
78
|
+
break;
|
79
|
+
case MLX90393_HALLCONF:
|
80
|
+
ret = this->mlx_.setHallConf(this->hallconf_);
|
81
|
+
break;
|
82
|
+
default:
|
83
|
+
break;
|
84
|
+
}
|
85
|
+
if (ret != MLX90393::STATUS_OK) {
|
86
|
+
ESP_LOGE(TAG, "failed to apply %s", LOG_STR_ARG(settings_to_string(which)));
|
87
|
+
}
|
88
|
+
return ret;
|
89
|
+
}
|
90
|
+
|
91
|
+
bool MLX90393Cls::apply_all_settings_() {
|
92
|
+
// perform dummy read after reset
|
93
|
+
// first one always gets NAK even tough everything is fine
|
94
|
+
uint8_t ignore = 0;
|
95
|
+
this->mlx_.getGainSel(ignore);
|
96
|
+
|
97
|
+
uint8_t result = MLX90393::STATUS_OK;
|
98
|
+
for (int i = MLX90393_GAIN_SEL; i != MLX90393_LAST; i++) {
|
99
|
+
MLX90393Setting stage = static_cast<MLX90393Setting>(i);
|
100
|
+
result |= this->apply_setting_(stage);
|
101
|
+
}
|
102
|
+
return result == MLX90393::STATUS_OK;
|
103
|
+
}
|
104
|
+
|
30
105
|
void MLX90393Cls::setup() {
|
31
106
|
ESP_LOGCONFIG(TAG, "Setting up MLX90393...");
|
32
107
|
// note the two arguments A0 and A1 which are used to construct an i2c address
|
@@ -34,19 +109,12 @@ void MLX90393Cls::setup() {
|
|
34
109
|
// see the transceive function above, which uses the address from I2CComponent
|
35
110
|
this->mlx_.begin_with_hal(this, 0, 0);
|
36
111
|
|
37
|
-
this->
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
this->mlx_.setOverSampling(this->oversampling_);
|
42
|
-
|
43
|
-
this->mlx_.setDigitalFiltering(this->filter_);
|
44
|
-
|
45
|
-
this->mlx_.setTemperatureOverSampling(this->temperature_oversampling_);
|
46
|
-
|
47
|
-
this->mlx_.setTemperatureCompensation(this->temperature_compensation_);
|
112
|
+
if (!this->apply_all_settings_()) {
|
113
|
+
this->mark_failed();
|
114
|
+
}
|
48
115
|
|
49
|
-
|
116
|
+
// start verify settings process
|
117
|
+
this->set_timeout("verify settings", 3000, [this]() { this->verify_settings_timeout_(MLX90393_GAIN_SEL); });
|
50
118
|
}
|
51
119
|
|
52
120
|
void MLX90393Cls::dump_config() {
|
@@ -91,5 +159,119 @@ void MLX90393Cls::update() {
|
|
91
159
|
}
|
92
160
|
}
|
93
161
|
|
162
|
+
bool MLX90393Cls::verify_setting_(MLX90393Setting which) {
|
163
|
+
uint8_t read_value = 0xFF;
|
164
|
+
uint8_t expected_value = 0xFF;
|
165
|
+
uint8_t read_status = -1;
|
166
|
+
char read_back_str[25] = {0};
|
167
|
+
|
168
|
+
switch (which) {
|
169
|
+
case MLX90393_GAIN_SEL: {
|
170
|
+
read_status = this->mlx_.getGainSel(read_value);
|
171
|
+
expected_value = this->gain_;
|
172
|
+
break;
|
173
|
+
}
|
174
|
+
|
175
|
+
case MLX90393_RESOLUTION: {
|
176
|
+
uint8_t read_resolutions[3] = {0xFF};
|
177
|
+
read_status = this->mlx_.getResolution(read_resolutions[0], read_resolutions[1], read_resolutions[2]);
|
178
|
+
snprintf(read_back_str, sizeof(read_back_str), "%u %u %u expected %u %u %u", read_resolutions[0],
|
179
|
+
read_resolutions[1], read_resolutions[2], this->resolutions_[0], this->resolutions_[1],
|
180
|
+
this->resolutions_[2]);
|
181
|
+
bool is_correct = true;
|
182
|
+
for (int i = 0; i < 3; i++) {
|
183
|
+
is_correct &= read_resolutions[i] == this->resolutions_[i];
|
184
|
+
}
|
185
|
+
if (is_correct) {
|
186
|
+
// set read_value and expected_value to same number, so the code blow recognizes it is correct
|
187
|
+
read_value = 0;
|
188
|
+
expected_value = 0;
|
189
|
+
} else {
|
190
|
+
// set to different numbers, to show incorrect
|
191
|
+
read_value = 1;
|
192
|
+
expected_value = 0;
|
193
|
+
}
|
194
|
+
break;
|
195
|
+
}
|
196
|
+
case MLX90393_OVER_SAMPLING: {
|
197
|
+
read_status = this->mlx_.getOverSampling(read_value);
|
198
|
+
expected_value = this->oversampling_;
|
199
|
+
break;
|
200
|
+
}
|
201
|
+
case MLX90393_DIGITAL_FILTERING: {
|
202
|
+
read_status = this->mlx_.getDigitalFiltering(read_value);
|
203
|
+
expected_value = this->filter_;
|
204
|
+
break;
|
205
|
+
}
|
206
|
+
case MLX90393_TEMPERATURE_OVER_SAMPLING: {
|
207
|
+
read_status = this->mlx_.getTemperatureOverSampling(read_value);
|
208
|
+
expected_value = this->temperature_oversampling_;
|
209
|
+
break;
|
210
|
+
}
|
211
|
+
case MLX90393_TEMPERATURE_COMPENSATION: {
|
212
|
+
read_status = this->mlx_.getTemperatureCompensation(read_value);
|
213
|
+
expected_value = (bool) this->temperature_compensation_;
|
214
|
+
break;
|
215
|
+
}
|
216
|
+
case MLX90393_HALLCONF: {
|
217
|
+
read_status = this->mlx_.getHallConf(read_value);
|
218
|
+
expected_value = this->hallconf_;
|
219
|
+
break;
|
220
|
+
}
|
221
|
+
default: {
|
222
|
+
return false;
|
223
|
+
}
|
224
|
+
}
|
225
|
+
if (read_status != MLX90393::STATUS_OK) {
|
226
|
+
ESP_LOGE(TAG, "verify error: failed to read %s", LOG_STR_ARG(settings_to_string(which)));
|
227
|
+
return false;
|
228
|
+
}
|
229
|
+
if (read_back_str[0] == 0x0) {
|
230
|
+
snprintf(read_back_str, sizeof(read_back_str), "%u expected %u", read_value, expected_value);
|
231
|
+
}
|
232
|
+
bool is_correct = read_value == expected_value;
|
233
|
+
if (!is_correct) {
|
234
|
+
ESP_LOGW(TAG, "verify failed: read back wrong %s: got %s", LOG_STR_ARG(settings_to_string(which)), read_back_str);
|
235
|
+
return false;
|
236
|
+
}
|
237
|
+
ESP_LOGD(TAG, "verify succeeded for %s. got %s", LOG_STR_ARG(settings_to_string(which)), read_back_str);
|
238
|
+
return true;
|
239
|
+
}
|
240
|
+
|
241
|
+
/**
|
242
|
+
* Regularly checks that our settings are still applied.
|
243
|
+
* Used to catch spurious chip resets.
|
244
|
+
*
|
245
|
+
* returns true if everything is fine.
|
246
|
+
* false if not
|
247
|
+
*/
|
248
|
+
void MLX90393Cls::verify_settings_timeout_(MLX90393Setting stage) {
|
249
|
+
bool is_setting_ok = this->verify_setting_(stage);
|
250
|
+
|
251
|
+
if (!is_setting_ok) {
|
252
|
+
if (this->mlx_.checkStatus(this->mlx_.reset()) != MLX90393::STATUS_OK) {
|
253
|
+
ESP_LOGE(TAG, "failed to reset device");
|
254
|
+
this->status_set_error();
|
255
|
+
this->mark_failed();
|
256
|
+
return;
|
257
|
+
}
|
258
|
+
|
259
|
+
if (!this->apply_all_settings_()) {
|
260
|
+
ESP_LOGE(TAG, "failed to re-apply settings");
|
261
|
+
this->status_set_error();
|
262
|
+
this->mark_failed();
|
263
|
+
} else {
|
264
|
+
ESP_LOGI(TAG, "reset and re-apply settings completed");
|
265
|
+
}
|
266
|
+
}
|
267
|
+
|
268
|
+
MLX90393Setting next_stage = static_cast<MLX90393Setting>(static_cast<int>(stage) + 1);
|
269
|
+
if (next_stage == MLX90393_LAST) {
|
270
|
+
next_stage = static_cast<MLX90393Setting>(0);
|
271
|
+
}
|
272
|
+
|
273
|
+
this->set_timeout("verify settings", 3000, [this, next_stage]() { this->verify_settings_timeout_(next_stage); });
|
274
|
+
}
|
275
|
+
|
94
276
|
} // namespace mlx90393
|
95
277
|
} // namespace esphome
|
@@ -1,15 +1,26 @@
|
|
1
1
|
#pragma once
|
2
2
|
|
3
|
-
#include "esphome/core/component.h"
|
4
|
-
#include "esphome/components/sensor/sensor.h"
|
5
|
-
#include "esphome/components/i2c/i2c.h"
|
6
|
-
#include "esphome/core/hal.h"
|
7
3
|
#include <MLX90393.h>
|
8
4
|
#include <MLX90393Hal.h>
|
5
|
+
#include "esphome/components/i2c/i2c.h"
|
6
|
+
#include "esphome/components/sensor/sensor.h"
|
7
|
+
#include "esphome/core/component.h"
|
8
|
+
#include "esphome/core/hal.h"
|
9
9
|
|
10
10
|
namespace esphome {
|
11
11
|
namespace mlx90393 {
|
12
12
|
|
13
|
+
enum MLX90393Setting {
|
14
|
+
MLX90393_GAIN_SEL = 0,
|
15
|
+
MLX90393_RESOLUTION,
|
16
|
+
MLX90393_OVER_SAMPLING,
|
17
|
+
MLX90393_DIGITAL_FILTERING,
|
18
|
+
MLX90393_TEMPERATURE_OVER_SAMPLING,
|
19
|
+
MLX90393_TEMPERATURE_COMPENSATION,
|
20
|
+
MLX90393_HALLCONF,
|
21
|
+
MLX90393_LAST,
|
22
|
+
};
|
23
|
+
|
13
24
|
class MLX90393Cls : public PollingComponent, public i2c::I2CDevice, public MLX90393Hal {
|
14
25
|
public:
|
15
26
|
void setup() override;
|
@@ -58,6 +69,12 @@ class MLX90393Cls : public PollingComponent, public i2c::I2CDevice, public MLX90
|
|
58
69
|
bool temperature_compensation_{false};
|
59
70
|
uint8_t hallconf_{0xC};
|
60
71
|
GPIOPin *drdy_pin_{nullptr};
|
72
|
+
|
73
|
+
bool apply_all_settings_();
|
74
|
+
uint8_t apply_setting_(MLX90393Setting which);
|
75
|
+
|
76
|
+
bool verify_setting_(MLX90393Setting which);
|
77
|
+
void verify_settings_timeout_(MLX90393Setting stage);
|
61
78
|
};
|
62
79
|
|
63
80
|
} // namespace mlx90393
|
@@ -1,6 +1,7 @@
|
|
1
1
|
#include "modbus.h"
|
2
2
|
#include "esphome/core/log.h"
|
3
3
|
#include "esphome/core/helpers.h"
|
4
|
+
#include "esphome/core/application.h"
|
4
5
|
|
5
6
|
namespace esphome {
|
6
7
|
namespace modbus {
|
@@ -13,7 +14,7 @@ void Modbus::setup() {
|
|
13
14
|
}
|
14
15
|
}
|
15
16
|
void Modbus::loop() {
|
16
|
-
const uint32_t now =
|
17
|
+
const uint32_t now = App.get_loop_component_start_time();
|
17
18
|
|
18
19
|
while (this->available()) {
|
19
20
|
uint8_t byte;
|
@@ -41,6 +41,7 @@ from esphome.const import (
|
|
41
41
|
CONF_REBOOT_TIMEOUT,
|
42
42
|
CONF_RETAIN,
|
43
43
|
CONF_SHUTDOWN_MESSAGE,
|
44
|
+
CONF_SKIP_CERT_CN_CHECK,
|
44
45
|
CONF_SSL_FINGERPRINTS,
|
45
46
|
CONF_STATE_TOPIC,
|
46
47
|
CONF_SUBSCRIBE_QOS,
|
@@ -67,7 +68,6 @@ def AUTO_LOAD():
|
|
67
68
|
|
68
69
|
CONF_DISCOVER_IP = "discover_ip"
|
69
70
|
CONF_IDF_SEND_ASYNC = "idf_send_async"
|
70
|
-
CONF_SKIP_CERT_CN_CHECK = "skip_cert_cn_check"
|
71
71
|
|
72
72
|
|
73
73
|
def validate_message_just_topic(value):
|
@@ -138,7 +138,11 @@ void MQTTClientComponent::send_device_info_() {
|
|
138
138
|
#endif
|
139
139
|
|
140
140
|
#ifdef USE_API_NOISE
|
141
|
-
|
141
|
+
if (api::global_api_server->get_noise_ctx()->has_psk()) {
|
142
|
+
root["api_encryption"] = "Noise_NNpsk0_25519_ChaChaPoly_SHA256";
|
143
|
+
} else {
|
144
|
+
root["api_encryption_supported"] = "Noise_NNpsk0_25519_ChaChaPoly_SHA256";
|
145
|
+
}
|
142
146
|
#endif
|
143
147
|
},
|
144
148
|
2, this->discovery_info_.retain);
|
@@ -341,7 +345,7 @@ void MQTTClientComponent::loop() {
|
|
341
345
|
this->disconnect_reason_.reset();
|
342
346
|
}
|
343
347
|
|
344
|
-
const uint32_t now =
|
348
|
+
const uint32_t now = App.get_loop_component_start_time();
|
345
349
|
|
346
350
|
switch (this->state_) {
|
347
351
|
case MQTT_CLIENT_DISABLED:
|
@@ -64,6 +64,8 @@ constexpr const char *const MQTT_DEVICE_NAME = "name";
|
|
64
64
|
constexpr const char *const MQTT_DEVICE_SUGGESTED_AREA = "sa";
|
65
65
|
constexpr const char *const MQTT_DEVICE_SW_VERSION = "sw";
|
66
66
|
constexpr const char *const MQTT_DEVICE_HW_VERSION = "hw";
|
67
|
+
constexpr const char *const MQTT_DIRECTION_COMMAND_TOPIC = "dir_cmd_t";
|
68
|
+
constexpr const char *const MQTT_DIRECTION_STATE_TOPIC = "dir_stat_t";
|
67
69
|
constexpr const char *const MQTT_DOCKED_TEMPLATE = "dock_tpl";
|
68
70
|
constexpr const char *const MQTT_DOCKED_TOPIC = "dock_t";
|
69
71
|
constexpr const char *const MQTT_EFFECT_COMMAND_TOPIC = "fx_cmd_t";
|
@@ -328,6 +330,8 @@ constexpr const char *const MQTT_DEVICE_NAME = "name";
|
|
328
330
|
constexpr const char *const MQTT_DEVICE_SUGGESTED_AREA = "suggested_area";
|
329
331
|
constexpr const char *const MQTT_DEVICE_SW_VERSION = "sw_version";
|
330
332
|
constexpr const char *const MQTT_DEVICE_HW_VERSION = "hw_version";
|
333
|
+
constexpr const char *const MQTT_DIRECTION_COMMAND_TOPIC = "direction_command_topic";
|
334
|
+
constexpr const char *const MQTT_DIRECTION_STATE_TOPIC = "direction_state_topic";
|
331
335
|
constexpr const char *const MQTT_DOCKED_TEMPLATE = "docked_template";
|
332
336
|
constexpr const char *const MQTT_DOCKED_TOPIC = "docked_topic";
|
333
337
|
constexpr const char *const MQTT_EFFECT_COMMAND_TOPIC = "effect_command_topic";
|
@@ -43,6 +43,32 @@ void MQTTFanComponent::setup() {
|
|
43
43
|
}
|
44
44
|
});
|
45
45
|
|
46
|
+
if (this->state_->get_traits().supports_direction()) {
|
47
|
+
this->subscribe(this->get_direction_command_topic(), [this](const std::string &topic, const std::string &payload) {
|
48
|
+
auto val = parse_on_off(payload.c_str(), "forward", "reverse");
|
49
|
+
switch (val) {
|
50
|
+
case PARSE_ON:
|
51
|
+
ESP_LOGD(TAG, "'%s': Setting direction FORWARD", this->friendly_name().c_str());
|
52
|
+
this->state_->make_call().set_direction(fan::FanDirection::FORWARD).perform();
|
53
|
+
break;
|
54
|
+
case PARSE_OFF:
|
55
|
+
ESP_LOGD(TAG, "'%s': Setting direction REVERSE", this->friendly_name().c_str());
|
56
|
+
this->state_->make_call().set_direction(fan::FanDirection::REVERSE).perform();
|
57
|
+
break;
|
58
|
+
case PARSE_TOGGLE:
|
59
|
+
this->state_->make_call()
|
60
|
+
.set_direction(this->state_->direction == fan::FanDirection::FORWARD ? fan::FanDirection::REVERSE
|
61
|
+
: fan::FanDirection::FORWARD)
|
62
|
+
.perform();
|
63
|
+
break;
|
64
|
+
case PARSE_NONE:
|
65
|
+
ESP_LOGW(TAG, "Unknown direction Payload %s", payload.c_str());
|
66
|
+
this->status_momentary_warning("direction", 5000);
|
67
|
+
break;
|
68
|
+
}
|
69
|
+
});
|
70
|
+
}
|
71
|
+
|
46
72
|
if (this->state_->get_traits().supports_oscillation()) {
|
47
73
|
this->subscribe(this->get_oscillation_command_topic(),
|
48
74
|
[this](const std::string &topic, const std::string &payload) {
|
@@ -94,6 +120,10 @@ void MQTTFanComponent::setup() {
|
|
94
120
|
void MQTTFanComponent::dump_config() {
|
95
121
|
ESP_LOGCONFIG(TAG, "MQTT Fan '%s': ", this->state_->get_name().c_str());
|
96
122
|
LOG_MQTT_COMPONENT(true, true);
|
123
|
+
if (this->state_->get_traits().supports_direction()) {
|
124
|
+
ESP_LOGCONFIG(TAG, " Direction State Topic: '%s'", this->get_direction_state_topic().c_str());
|
125
|
+
ESP_LOGCONFIG(TAG, " Direction Command Topic: '%s'", this->get_direction_command_topic().c_str());
|
126
|
+
}
|
97
127
|
if (this->state_->get_traits().supports_oscillation()) {
|
98
128
|
ESP_LOGCONFIG(TAG, " Oscillation State Topic: '%s'", this->get_oscillation_state_topic().c_str());
|
99
129
|
ESP_LOGCONFIG(TAG, " Oscillation Command Topic: '%s'", this->get_oscillation_command_topic().c_str());
|
@@ -107,6 +137,10 @@ void MQTTFanComponent::dump_config() {
|
|
107
137
|
bool MQTTFanComponent::send_initial_state() { return this->publish_state(); }
|
108
138
|
|
109
139
|
void MQTTFanComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
|
140
|
+
if (this->state_->get_traits().supports_direction()) {
|
141
|
+
root[MQTT_DIRECTION_COMMAND_TOPIC] = this->get_direction_command_topic();
|
142
|
+
root[MQTT_DIRECTION_STATE_TOPIC] = this->get_direction_state_topic();
|
143
|
+
}
|
110
144
|
if (this->state_->get_traits().supports_oscillation()) {
|
111
145
|
root[MQTT_OSCILLATION_COMMAND_TOPIC] = this->get_oscillation_command_topic();
|
112
146
|
root[MQTT_OSCILLATION_STATE_TOPIC] = this->get_oscillation_state_topic();
|
@@ -122,6 +156,11 @@ bool MQTTFanComponent::publish_state() {
|
|
122
156
|
ESP_LOGD(TAG, "'%s' Sending state %s.", this->state_->get_name().c_str(), state_s);
|
123
157
|
this->publish(this->get_state_topic_(), state_s);
|
124
158
|
bool failed = false;
|
159
|
+
if (this->state_->get_traits().supports_direction()) {
|
160
|
+
bool success = this->publish(this->get_direction_state_topic(),
|
161
|
+
this->state_->direction == fan::FanDirection::FORWARD ? "forward" : "reverse");
|
162
|
+
failed = failed || !success;
|
163
|
+
}
|
125
164
|
if (this->state_->get_traits().supports_oscillation()) {
|
126
165
|
bool success = this->publish(this->get_oscillation_state_topic(),
|
127
166
|
this->state_->oscillating ? "oscillate_on" : "oscillate_off");
|
@@ -15,6 +15,8 @@ class MQTTFanComponent : public mqtt::MQTTComponent {
|
|
15
15
|
public:
|
16
16
|
explicit MQTTFanComponent(fan::Fan *state);
|
17
17
|
|
18
|
+
MQTT_COMPONENT_CUSTOM_TOPIC(direction, command)
|
19
|
+
MQTT_COMPONENT_CUSTOM_TOPIC(direction, state)
|
18
20
|
MQTT_COMPONENT_CUSTOM_TOPIC(oscillation, command)
|
19
21
|
MQTT_COMPONENT_CUSTOM_TOPIC(oscillation, state)
|
20
22
|
MQTT_COMPONENT_CUSTOM_TOPIC(speed_level, command)
|
@@ -24,13 +24,13 @@ CONFIG_SCHEMA = (
|
|
24
24
|
cv.Schema(
|
25
25
|
{
|
26
26
|
cv.GenerateID(): cv.declare_id(MS5611Component),
|
27
|
-
cv.
|
27
|
+
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
|
28
28
|
unit_of_measurement=UNIT_CELSIUS,
|
29
29
|
accuracy_decimals=1,
|
30
30
|
device_class=DEVICE_CLASS_TEMPERATURE,
|
31
31
|
state_class=STATE_CLASS_MEASUREMENT,
|
32
32
|
),
|
33
|
-
cv.
|
33
|
+
cv.Optional(CONF_PRESSURE): sensor.sensor_schema(
|
34
34
|
unit_of_measurement=UNIT_HECTOPASCAL,
|
35
35
|
icon=ICON_GAUGE,
|
36
36
|
accuracy_decimals=1,
|
@@ -49,10 +49,10 @@ async def to_code(config):
|
|
49
49
|
await cg.register_component(var, config)
|
50
50
|
await i2c.register_i2c_device(var, config)
|
51
51
|
|
52
|
-
if
|
53
|
-
sens = await sensor.new_sensor(
|
52
|
+
if temperature := config.get(CONF_TEMPERATURE):
|
53
|
+
sens = await sensor.new_sensor(temperature)
|
54
54
|
cg.add(var.set_temperature_sensor(sens))
|
55
55
|
|
56
|
-
if
|
57
|
-
sens = await sensor.new_sensor(
|
56
|
+
if pressure := config.get(CONF_PRESSURE):
|
57
|
+
sens = await sensor.new_sensor(pressure)
|
58
58
|
cg.add(var.set_pressure_sensor(sens))
|
@@ -29,19 +29,19 @@ CONFIG_SCHEMA = (
|
|
29
29
|
cv.Schema(
|
30
30
|
{
|
31
31
|
cv.GenerateID(): cv.declare_id(MS8607Component),
|
32
|
-
cv.
|
32
|
+
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
|
33
33
|
unit_of_measurement=UNIT_CELSIUS,
|
34
34
|
accuracy_decimals=2, # Resolution: 0.01
|
35
35
|
device_class=DEVICE_CLASS_TEMPERATURE,
|
36
36
|
state_class=STATE_CLASS_MEASUREMENT,
|
37
37
|
),
|
38
|
-
cv.
|
38
|
+
cv.Optional(CONF_PRESSURE): sensor.sensor_schema(
|
39
39
|
unit_of_measurement=UNIT_HECTOPASCAL,
|
40
40
|
accuracy_decimals=2, # Resolution: 0.016
|
41
41
|
device_class=DEVICE_CLASS_PRESSURE,
|
42
42
|
state_class=STATE_CLASS_MEASUREMENT,
|
43
43
|
),
|
44
|
-
cv.
|
44
|
+
cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(
|
45
45
|
unit_of_measurement=UNIT_PERCENT,
|
46
46
|
accuracy_decimals=2, # Resolution: 0.04
|
47
47
|
device_class=DEVICE_CLASS_HUMIDITY,
|
@@ -7,28 +7,29 @@ from esphome.const import CONF_BACKGROUND_COLOR, CONF_FOREGROUND_COLOR, CONF_VIS
|
|
7
7
|
|
8
8
|
from . import CONF_NEXTION_ID, Nextion
|
9
9
|
|
10
|
-
|
10
|
+
CONF_AUTO_WAKE_ON_TOUCH = "auto_wake_on_touch"
|
11
|
+
CONF_BACKGROUND_PRESSED_COLOR = "background_pressed_color"
|
12
|
+
CONF_COMMAND_SPACING = "command_spacing"
|
11
13
|
CONF_COMPONENT_NAME = "component_name"
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
CONF_EXIT_REPARSE_ON_START = "exit_reparse_on_start"
|
15
|
+
CONF_FONT_ID = "font_id"
|
16
|
+
CONF_FOREGROUND_PRESSED_COLOR = "foreground_pressed_color"
|
17
|
+
CONF_ON_BUFFER_OVERFLOW = "on_buffer_overflow"
|
18
|
+
CONF_ON_PAGE = "on_page"
|
19
|
+
CONF_ON_SETUP = "on_setup"
|
17
20
|
CONF_ON_SLEEP = "on_sleep"
|
18
21
|
CONF_ON_WAKE = "on_wake"
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
+
CONF_PRECISION = "precision"
|
23
|
+
CONF_SKIP_CONNECTION_HANDSHAKE = "skip_connection_handshake"
|
24
|
+
CONF_START_UP_PAGE = "start_up_page"
|
25
|
+
CONF_TFT_URL = "tft_url"
|
22
26
|
CONF_TOUCH_SLEEP_TIMEOUT = "touch_sleep_timeout"
|
27
|
+
CONF_VARIABLE_NAME = "variable_name"
|
23
28
|
CONF_WAKE_UP_PAGE = "wake_up_page"
|
24
|
-
|
25
|
-
CONF_AUTO_WAKE_ON_TOUCH = "auto_wake_on_touch"
|
29
|
+
CONF_WAVE_CHANNEL_ID = "wave_channel_id"
|
26
30
|
CONF_WAVE_MAX_LENGTH = "wave_max_length"
|
27
|
-
|
28
|
-
|
29
|
-
CONF_FONT_ID = "font_id"
|
30
|
-
CONF_EXIT_REPARSE_ON_START = "exit_reparse_on_start"
|
31
|
-
CONF_SKIP_CONNECTION_HANDSHAKE = "skip_connection_handshake"
|
31
|
+
CONF_WAVE_MAX_VALUE = "wave_max_value"
|
32
|
+
CONF_WAVEFORM_SEND_LAST_VALUE = "waveform_send_last_value"
|
32
33
|
|
33
34
|
|
34
35
|
def NextionName(value):
|
@@ -9,16 +9,17 @@ from esphome.const import (
|
|
9
9
|
CONF_ON_TOUCH,
|
10
10
|
CONF_TRIGGER_ID,
|
11
11
|
)
|
12
|
-
from esphome.core import CORE
|
12
|
+
from esphome.core import CORE, TimePeriod
|
13
13
|
|
14
14
|
from . import Nextion, nextion_ns, nextion_ref
|
15
15
|
from .base_component import (
|
16
16
|
CONF_AUTO_WAKE_ON_TOUCH,
|
17
|
+
CONF_COMMAND_SPACING,
|
17
18
|
CONF_EXIT_REPARSE_ON_START,
|
18
19
|
CONF_ON_BUFFER_OVERFLOW,
|
19
|
-
CONF_ON_PAGE,
|
20
20
|
CONF_ON_SETUP,
|
21
21
|
CONF_ON_SLEEP,
|
22
|
+
CONF_ON_PAGE,
|
22
23
|
CONF_ON_WAKE,
|
23
24
|
CONF_SKIP_CONNECTION_HANDSHAKE,
|
24
25
|
CONF_START_UP_PAGE,
|
@@ -88,6 +89,10 @@ CONFIG_SCHEMA = (
|
|
88
89
|
cv.Optional(CONF_AUTO_WAKE_ON_TOUCH, default=True): cv.boolean,
|
89
90
|
cv.Optional(CONF_EXIT_REPARSE_ON_START, default=False): cv.boolean,
|
90
91
|
cv.Optional(CONF_SKIP_CONNECTION_HANDSHAKE, default=False): cv.boolean,
|
92
|
+
cv.Optional(CONF_COMMAND_SPACING): cv.All(
|
93
|
+
cv.positive_time_period_milliseconds,
|
94
|
+
cv.Range(max=TimePeriod(milliseconds=255)),
|
95
|
+
),
|
91
96
|
}
|
92
97
|
)
|
93
98
|
.extend(cv.polling_component_schema("5s"))
|
@@ -120,6 +125,10 @@ async def to_code(config):
|
|
120
125
|
var = cg.new_Pvariable(config[CONF_ID])
|
121
126
|
await uart.register_uart_device(var, config)
|
122
127
|
|
128
|
+
if command_spacing := config.get(CONF_COMMAND_SPACING):
|
129
|
+
cg.add_define("USE_NEXTION_COMMAND_SPACING")
|
130
|
+
cg.add(var.set_command_spacing(command_spacing.total_milliseconds))
|
131
|
+
|
123
132
|
if CONF_BRIGHTNESS in config:
|
124
133
|
cg.add(var.set_brightness(config[CONF_BRIGHTNESS]))
|
125
134
|
|
@@ -31,11 +31,22 @@ bool Nextion::send_command_(const std::string &command) {
|
|
31
31
|
return false;
|
32
32
|
}
|
33
33
|
|
34
|
+
#ifdef USE_NEXTION_COMMAND_SPACING
|
35
|
+
if (!this->ignore_is_setup_ && !this->command_pacer_.can_send()) {
|
36
|
+
return false;
|
37
|
+
}
|
38
|
+
#endif // USE_NEXTION_COMMAND_SPACING
|
39
|
+
|
34
40
|
ESP_LOGN(TAG, "send_command %s", command.c_str());
|
35
41
|
|
36
42
|
this->write_str(command.c_str());
|
37
43
|
const uint8_t to_send[3] = {0xFF, 0xFF, 0xFF};
|
38
44
|
this->write_array(to_send, sizeof(to_send));
|
45
|
+
|
46
|
+
#ifdef USE_NEXTION_COMMAND_SPACING
|
47
|
+
this->command_pacer_.mark_sent();
|
48
|
+
#endif // USE_NEXTION_COMMAND_SPACING
|
49
|
+
|
39
50
|
return true;
|
40
51
|
}
|
41
52
|
|
@@ -158,6 +169,10 @@ void Nextion::dump_config() {
|
|
158
169
|
if (this->start_up_page_ != -1) {
|
159
170
|
ESP_LOGCONFIG(TAG, " Start Up Page: %" PRId16, this->start_up_page_);
|
160
171
|
}
|
172
|
+
|
173
|
+
#ifdef USE_NEXTION_COMMAND_SPACING
|
174
|
+
ESP_LOGCONFIG(TAG, " Command spacing: %" PRIu8 "ms", this->command_pacer_.get_spacing());
|
175
|
+
#endif // USE_NEXTION_COMMAND_SPACING
|
161
176
|
}
|
162
177
|
|
163
178
|
float Nextion::get_setup_priority() const { return setup_priority::DATA; }
|
@@ -312,6 +327,11 @@ bool Nextion::remove_from_q_(bool report_empty) {
|
|
312
327
|
}
|
313
328
|
|
314
329
|
NextionQueue *nb = this->nextion_queue_.front();
|
330
|
+
if (!nb || !nb->component) {
|
331
|
+
ESP_LOGE(TAG, "Invalid queue entry!");
|
332
|
+
this->nextion_queue_.pop_front();
|
333
|
+
return false;
|
334
|
+
}
|
315
335
|
NextionComponentBase *component = nb->component;
|
316
336
|
|
317
337
|
ESP_LOGN(TAG, "Removing %s from the queue", component->get_variable_name().c_str());
|
@@ -341,6 +361,12 @@ void Nextion::process_nextion_commands_() {
|
|
341
361
|
return;
|
342
362
|
}
|
343
363
|
|
364
|
+
#ifdef USE_NEXTION_COMMAND_SPACING
|
365
|
+
if (!this->command_pacer_.can_send()) {
|
366
|
+
return; // Will try again in next loop iteration
|
367
|
+
}
|
368
|
+
#endif
|
369
|
+
|
344
370
|
size_t to_process_length = 0;
|
345
371
|
std::string to_process;
|
346
372
|
|
@@ -380,7 +406,9 @@ void Nextion::process_nextion_commands_() {
|
|
380
406
|
this->setup_callback_.call();
|
381
407
|
}
|
382
408
|
}
|
383
|
-
|
409
|
+
#ifdef USE_NEXTION_COMMAND_SPACING
|
410
|
+
this->command_pacer_.mark_sent(); // Here is where we should mark the command as sent
|
411
|
+
#endif
|
384
412
|
break;
|
385
413
|
case 0x02: // invalid Component ID or name was used
|
386
414
|
ESP_LOGW(TAG, "Nextion reported component ID or name invalid!");
|
@@ -524,6 +552,11 @@ void Nextion::process_nextion_commands_() {
|
|
524
552
|
}
|
525
553
|
|
526
554
|
NextionQueue *nb = this->nextion_queue_.front();
|
555
|
+
if (!nb || !nb->component) {
|
556
|
+
ESP_LOGE(TAG, "Invalid queue entry!");
|
557
|
+
this->nextion_queue_.pop_front();
|
558
|
+
return;
|
559
|
+
}
|
527
560
|
NextionComponentBase *component = nb->component;
|
528
561
|
|
529
562
|
if (component->get_queue_type() != NextionQueueType::TEXT_SENSOR) {
|
@@ -564,6 +597,11 @@ void Nextion::process_nextion_commands_() {
|
|
564
597
|
}
|
565
598
|
|
566
599
|
NextionQueue *nb = this->nextion_queue_.front();
|
600
|
+
if (!nb || !nb->component) {
|
601
|
+
ESP_LOGE(TAG, "Invalid queue entry!");
|
602
|
+
this->nextion_queue_.pop_front();
|
603
|
+
return;
|
604
|
+
}
|
567
605
|
NextionComponentBase *component = nb->component;
|
568
606
|
|
569
607
|
if (component->get_queue_type() != NextionQueueType::SENSOR &&
|