esphome 2024.12.3__py3-none-any.whl → 2025.2.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 -3
- esphome/components/adc/__init__.py +17 -11
- esphome/components/adc/adc_sensor.h +17 -0
- esphome/components/adc/adc_sensor_common.cpp +55 -0
- esphome/components/adc/adc_sensor_esp32.cpp +8 -5
- esphome/components/adc/adc_sensor_esp8266.cpp +10 -6
- esphome/components/adc/adc_sensor_libretiny.cpp +11 -6
- esphome/components/adc/adc_sensor_rp2040.cpp +13 -10
- esphome/components/adc/sensor.py +9 -3
- esphome/components/ads1115/ads1115.cpp +56 -7
- esphome/components/ads1115/ads1115.h +13 -1
- esphome/components/ads1115/sensor/__init__.py +16 -0
- esphome/components/ads1115/sensor/ads1115_sensor.cpp +2 -1
- esphome/components/ads1115/sensor/ads1115_sensor.h +2 -0
- esphome/components/animation/__init__.py +23 -261
- esphome/components/animation/animation.cpp +2 -2
- esphome/components/animation/animation.h +2 -1
- esphome/components/api/api_pb2.cpp +14 -0
- esphome/components/api/api_pb2.h +1 -0
- esphome/components/api/client.py +8 -3
- esphome/components/audio/__init__.py +112 -0
- esphome/components/audio/audio.cpp +67 -0
- esphome/components/audio/audio.h +125 -7
- esphome/components/audio/audio_decoder.cpp +361 -0
- esphome/components/audio/audio_decoder.h +135 -0
- esphome/components/audio/audio_reader.cpp +308 -0
- esphome/components/audio/audio_reader.h +85 -0
- esphome/components/audio/audio_resampler.cpp +159 -0
- esphome/components/audio/audio_resampler.h +101 -0
- esphome/components/audio/audio_transfer_buffer.cpp +165 -0
- esphome/components/audio/audio_transfer_buffer.h +139 -0
- esphome/components/audio_adc/__init__.py +41 -0
- esphome/components/audio_adc/audio_adc.h +17 -0
- esphome/components/audio_adc/automation.h +23 -0
- esphome/components/bk72xx/__init__.py +1 -0
- esphome/components/ble_client/ble_client.cpp +1 -2
- esphome/components/ble_client/sensor/__init__.py +1 -1
- esphome/components/ble_client/text_sensor/__init__.py +1 -1
- esphome/components/bluetooth_proxy/bluetooth_connection.cpp +5 -0
- esphome/components/bluetooth_proxy/bluetooth_connection.h +1 -0
- esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +5 -0
- esphome/components/ch422g/ch422g.h +2 -0
- esphome/components/climate/__init__.py +1 -1
- esphome/components/climate_ir/climate_ir.cpp +2 -1
- esphome/components/coolix/coolix.cpp +2 -1
- esphome/components/cse7766/cse7766.cpp +8 -16
- esphome/components/custom/__init__.py +0 -3
- esphome/components/custom/binary_sensor/__init__.py +2 -28
- esphome/components/custom/climate/__init__.py +2 -27
- esphome/components/custom/cover/__init__.py +2 -27
- esphome/components/custom/light/__init__.py +2 -27
- esphome/components/custom/output/__init__.py +2 -58
- esphome/components/custom/sensor/__init__.py +2 -24
- esphome/components/custom/switch/__init__.py +2 -24
- esphome/components/custom/text_sensor/__init__.py +2 -29
- esphome/components/custom_component/__init__.py +3 -27
- esphome/components/daly_bms/daly_bms.cpp +6 -0
- esphome/components/daly_bms/daly_bms.h +2 -0
- esphome/components/daly_bms/sensor.py +6 -0
- esphome/components/debug/debug_component.cpp +4 -0
- esphome/components/debug/debug_component.h +14 -0
- esphome/components/debug/debug_esp32.cpp +154 -74
- esphome/components/dfplayer/dfplayer.cpp +15 -2
- esphome/components/dfrobot_sen0395/dfrobot_sen0395.cpp +2 -1
- esphome/components/dht/dht.cpp +4 -2
- esphome/components/dht/sensor.py +1 -1
- esphome/components/display/__init__.py +18 -5
- esphome/components/display/display.cpp +16 -3
- esphome/components/display/rect.cpp +2 -1
- esphome/components/es7210/__init__.py +0 -0
- esphome/components/es7210/audio_adc.py +51 -0
- esphome/components/es7210/es7210.cpp +228 -0
- esphome/components/es7210/es7210.h +62 -0
- esphome/components/es7210/es7210_const.h +129 -0
- esphome/components/es7243e/__init__.py +0 -0
- esphome/components/es7243e/audio_adc.py +34 -0
- esphome/components/es7243e/es7243e.cpp +125 -0
- esphome/components/es7243e/es7243e.h +37 -0
- esphome/components/es7243e/es7243e_const.h +54 -0
- esphome/components/es8156/__init__.py +0 -0
- esphome/components/es8156/audio_dac.py +27 -0
- esphome/components/es8156/es8156.cpp +87 -0
- esphome/components/es8156/es8156.h +51 -0
- esphome/components/es8156/es8156_const.h +68 -0
- esphome/components/es8311/audio_dac.py +1 -2
- esphome/components/esp32/__init__.py +1 -0
- esphome/components/esp32/core.cpp +5 -1
- esphome/components/esp32/gpio.h +2 -0
- esphome/components/esp32_ble/__init__.py +39 -0
- esphome/components/esp32_ble/queue.h +4 -4
- esphome/components/esp32_ble_client/ble_client_base.cpp +46 -0
- esphome/components/esp32_ble_client/ble_client_base.h +2 -0
- esphome/components/esp32_ble_server/__init__.py +582 -12
- esphome/components/esp32_ble_server/ble_characteristic.cpp +48 -60
- esphome/components/esp32_ble_server/ble_characteristic.h +24 -17
- esphome/components/esp32_ble_server/ble_descriptor.cpp +21 -9
- esphome/components/esp32_ble_server/ble_descriptor.h +17 -6
- esphome/components/esp32_ble_server/ble_server.cpp +62 -67
- esphome/components/esp32_ble_server/ble_server.h +28 -32
- esphome/components/esp32_ble_server/ble_server_automations.cpp +77 -0
- esphome/components/esp32_ble_server/ble_server_automations.h +115 -0
- esphome/components/esp32_ble_server/ble_service.cpp +17 -15
- esphome/components/esp32_ble_server/ble_service.h +10 -14
- esphome/components/esp32_ble_tracker/__init__.py +6 -39
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +33 -10
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +8 -4
- esphome/components/esp32_dac/esp32_dac.cpp +16 -7
- esphome/components/esp32_dac/esp32_dac.h +8 -0
- esphome/components/esp32_dac/output.py +16 -4
- esphome/components/esp32_improv/__init__.py +2 -8
- esphome/components/esp32_improv/esp32_improv_component.cpp +21 -20
- esphome/components/esp32_improv/esp32_improv_component.h +3 -4
- esphome/components/esp32_rmt/__init__.py +28 -3
- esphome/components/esp32_rmt_led_strip/led_strip.cpp +73 -6
- esphome/components/esp32_rmt_led_strip/led_strip.h +21 -3
- esphome/components/esp32_rmt_led_strip/light.py +72 -7
- esphome/components/esp32_touch/esp32_touch.cpp +5 -0
- esphome/components/esp8266/__init__.py +1 -0
- esphome/components/esp8266/gpio.h +1 -0
- esphome/components/ethernet/__init__.py +10 -10
- esphome/components/event/event.cpp +4 -2
- esphome/components/event/event.h +2 -0
- esphome/components/event_emitter/__init__.py +5 -0
- esphome/components/event_emitter/event_emitter.cpp +14 -0
- esphome/components/event_emitter/event_emitter.h +63 -0
- esphome/components/font/__init__.py +1 -1
- esphome/components/gcja5/gcja5.cpp +2 -1
- esphome/components/graph/graph.cpp +4 -9
- esphome/components/haier/haier_base.cpp +2 -1
- esphome/components/haier/hon_climate.cpp +2 -1
- esphome/components/heatpumpir/heatpumpir.cpp +2 -1
- esphome/components/host/__init__.py +1 -0
- esphome/components/host/gpio.h +1 -0
- esphome/components/http_request/http_request.h +2 -2
- esphome/components/http_request/http_request_arduino.cpp +1 -1
- esphome/components/http_request/http_request_idf.cpp +1 -1
- esphome/components/i2c/i2c_bus_esp_idf.cpp +4 -0
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +7 -5
- esphome/components/i2s_audio/speaker/__init__.py +53 -6
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +92 -46
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +8 -0
- esphome/components/ili9xxx/display.py +29 -11
- esphome/components/ili9xxx/ili9xxx_display.cpp +2 -5
- esphome/components/ili9xxx/ili9xxx_display.h +2 -1
- esphome/components/image/__init__.py +443 -255
- esphome/components/image/image.cpp +115 -61
- esphome/components/image/image.h +15 -24
- esphome/components/json/json_util.cpp +8 -34
- esphome/components/libretiny/__init__.py +1 -0
- esphome/components/libretiny/gpio_arduino.h +1 -0
- esphome/components/light/light_color_values.h +1 -1
- esphome/components/logger/__init__.py +45 -9
- esphome/components/logger/logger.cpp +16 -14
- esphome/components/logger/logger.h +11 -7
- esphome/components/logger/select/__init__.py +29 -0
- esphome/components/logger/select/logger_level_select.cpp +27 -0
- esphome/components/logger/select/logger_level_select.h +15 -0
- esphome/components/lvgl/__init__.py +96 -73
- esphome/components/lvgl/automation.py +39 -7
- esphome/components/lvgl/defines.py +8 -2
- esphome/components/lvgl/lvgl_esphome.cpp +8 -15
- esphome/components/lvgl/lvgl_esphome.h +20 -5
- esphome/components/lvgl/schemas.py +25 -14
- esphome/components/lvgl/trigger.py +27 -3
- esphome/components/lvgl/widgets/dropdown.py +1 -1
- esphome/components/lvgl/widgets/keyboard.py +8 -1
- esphome/components/lvgl/widgets/meter.py +2 -1
- esphome/components/lvgl/widgets/msgbox.py +1 -1
- esphome/components/lvgl/widgets/obj.py +1 -12
- esphome/components/lvgl/widgets/page.py +37 -2
- esphome/components/lvgl/widgets/tabview.py +1 -1
- esphome/components/max6956/max6956.h +2 -0
- esphome/components/mcp23016/mcp23016.h +2 -0
- esphome/components/mcp23xxx_base/mcp23xxx_base.h +2 -0
- esphome/components/mdns/__init__.py +1 -1
- esphome/components/media_player/__init__.py +37 -8
- esphome/components/media_player/automation.h +11 -2
- esphome/components/media_player/media_player.cpp +8 -0
- esphome/components/media_player/media_player.h +8 -4
- esphome/components/micronova/switch/micronova_switch.cpp +4 -2
- esphome/components/midea/ac_automations.h +3 -1
- esphome/components/midea/air_conditioner.cpp +7 -5
- esphome/components/midea/air_conditioner.h +1 -1
- esphome/components/midea/climate.py +4 -2
- esphome/components/midea/ir_transmitter.h +36 -5
- esphome/components/mixer/__init__.py +0 -0
- esphome/components/mixer/speaker/__init__.py +172 -0
- esphome/components/mixer/speaker/automation.h +19 -0
- esphome/components/mixer/speaker/mixer_speaker.cpp +624 -0
- esphome/components/mixer/speaker/mixer_speaker.h +207 -0
- esphome/components/modbus_controller/text_sensor/modbus_textsensor.cpp +7 -13
- esphome/components/mpr121/mpr121.h +2 -0
- esphome/components/mqtt/__init__.py +1 -1
- esphome/components/mqtt/mqtt_client.cpp +7 -1
- esphome/components/mqtt/mqtt_client.h +1 -1
- esphome/components/mqtt/mqtt_climate.cpp +2 -2
- esphome/components/network/ip_address.h +2 -0
- esphome/components/nextion/automation.h +17 -0
- esphome/components/nextion/display.py +42 -17
- esphome/components/nextion/nextion.cpp +4 -10
- esphome/components/nextion/nextion.h +89 -82
- esphome/components/nextion/nextion_commands.cpp +10 -10
- esphome/components/ntc/sensor.py +2 -4
- esphome/components/online_image/__init__.py +98 -46
- esphome/components/online_image/bmp_image.cpp +101 -0
- esphome/components/online_image/bmp_image.h +40 -0
- esphome/components/online_image/image_decoder.cpp +31 -2
- esphome/components/online_image/image_decoder.h +24 -15
- esphome/components/online_image/jpeg_image.cpp +92 -0
- esphome/components/online_image/jpeg_image.h +34 -0
- esphome/components/online_image/online_image.cpp +118 -58
- esphome/components/online_image/online_image.h +39 -9
- esphome/components/online_image/png_image.cpp +7 -3
- esphome/components/online_image/png_image.h +2 -1
- esphome/components/opentherm/__init__.py +73 -7
- esphome/components/opentherm/automation.h +25 -0
- esphome/components/opentherm/const.py +1 -0
- esphome/components/opentherm/generate.py +39 -6
- esphome/components/opentherm/hub.cpp +117 -79
- esphome/components/opentherm/hub.h +31 -15
- esphome/components/opentherm/opentherm.cpp +47 -23
- esphome/components/opentherm/opentherm.h +27 -6
- esphome/components/opentherm/opentherm_macros.h +11 -0
- esphome/components/opentherm/schema.py +78 -1
- esphome/components/opentherm/validate.py +7 -2
- esphome/components/pca6416a/pca6416a.h +2 -0
- esphome/components/pca9554/pca9554.h +2 -0
- esphome/components/pcf8574/pcf8574.h +2 -0
- esphome/components/preferences/__init__.py +2 -4
- esphome/components/preferences/syncer.h +10 -3
- esphome/components/prometheus/prometheus_handler.cpp +313 -0
- esphome/components/prometheus/prometheus_handler.h +48 -7
- esphome/components/psram/psram.cpp +8 -1
- esphome/components/pulse_counter/pulse_counter_sensor.cpp +14 -9
- esphome/components/pulse_counter/pulse_counter_sensor.h +4 -4
- esphome/components/pulse_meter/pulse_meter_sensor.cpp +2 -0
- esphome/components/qspi_dbi/__init__.py +3 -0
- esphome/components/qspi_dbi/display.py +74 -47
- esphome/components/qspi_dbi/models.py +245 -2
- esphome/components/qspi_dbi/qspi_dbi.cpp +9 -16
- esphome/components/qspi_dbi/qspi_dbi.h +2 -2
- esphome/components/remote_base/__init__.py +77 -25
- esphome/components/remote_base/remote_base.cpp +1 -1
- esphome/components/remote_base/remote_base.h +20 -2
- esphome/components/remote_base/toto_protocol.cpp +100 -0
- esphome/components/remote_base/toto_protocol.h +45 -0
- esphome/components/remote_receiver/__init__.py +55 -10
- esphome/components/remote_receiver/remote_receiver.h +36 -3
- esphome/components/remote_receiver/remote_receiver_esp32.cpp +145 -6
- esphome/components/remote_transmitter/__init__.py +62 -4
- esphome/components/remote_transmitter/remote_transmitter.h +21 -2
- esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +140 -4
- esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +3 -3
- esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +3 -3
- esphome/components/resampler/__init__.py +0 -0
- esphome/components/resampler/speaker/__init__.py +103 -0
- esphome/components/resampler/speaker/resampler_speaker.cpp +318 -0
- esphome/components/resampler/speaker/resampler_speaker.h +107 -0
- esphome/components/resistance/resistance_sensor.h +2 -3
- esphome/components/resistance/sensor.py +2 -9
- esphome/components/rotary_encoder/rotary_encoder.cpp +8 -4
- esphome/components/rp2040/__init__.py +1 -0
- esphome/components/rp2040/gpio.h +1 -0
- esphome/components/rtl87xx/__init__.py +2 -0
- esphome/components/scd30/sensor.py +1 -1
- esphome/components/sdl/binary_sensor.py +270 -0
- esphome/components/sdl/sdl_esphome.cpp +16 -0
- esphome/components/sdl/sdl_esphome.h +9 -0
- esphome/components/seeed_mr60bha2/binary_sensor.py +25 -0
- esphome/components/seeed_mr60bha2/seeed_mr60bha2.cpp +26 -2
- esphome/components/seeed_mr60bha2/seeed_mr60bha2.h +9 -20
- esphome/components/seeed_mr60bha2/sensor.py +9 -1
- esphome/components/sn74hc165/sn74hc165.h +3 -0
- esphome/components/sn74hc595/sn74hc595.h +3 -0
- esphome/components/speaker/__init__.py +5 -4
- esphome/components/speaker/media_player/__init__.py +458 -0
- esphome/components/speaker/media_player/audio_pipeline.cpp +568 -0
- esphome/components/speaker/media_player/audio_pipeline.h +159 -0
- esphome/components/speaker/media_player/automation.h +26 -0
- esphome/components/speaker/media_player/speaker_media_player.cpp +577 -0
- esphome/components/speaker/media_player/speaker_media_player.h +160 -0
- esphome/components/speaker/speaker.h +20 -0
- esphome/components/spi/__init__.py +1 -5
- esphome/components/spi/spi.cpp +7 -1
- esphome/components/spi/spi.h +21 -2
- esphome/components/spi_led_strip/light.py +3 -5
- esphome/components/spi_led_strip/spi_led_strip.cpp +67 -0
- esphome/components/spi_led_strip/spi_led_strip.h +8 -60
- esphome/components/sprinkler/sprinkler.cpp +3 -1
- esphome/components/sx1509/sx1509_gpio_pin.h +2 -0
- esphome/components/tca9555/tca9555.h +2 -0
- esphome/components/toshiba/toshiba.cpp +2 -1
- esphome/components/tuya/light/tuya_light.cpp +4 -2
- esphome/components/uart/uart_component_esp32_arduino.cpp +2 -2
- esphome/components/uart/uart_component_esp_idf.cpp +2 -2
- esphome/components/udp/__init__.py +8 -2
- esphome/components/udp/udp_component.cpp +25 -56
- esphome/components/udp/udp_component.h +3 -0
- esphome/components/uponor_smatrix/sensor/__init__.py +14 -4
- esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.cpp +5 -0
- esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.h +1 -0
- esphome/components/uptime/text_sensor/__init__.py +19 -0
- esphome/components/uptime/text_sensor/uptime_text_sensor.cpp +63 -0
- esphome/components/uptime/text_sensor/uptime_text_sensor.h +25 -0
- esphome/components/voice_assistant/voice_assistant.cpp +24 -14
- esphome/components/voice_assistant/voice_assistant.h +8 -0
- esphome/components/waveshare_epaper/display.py +22 -1
- esphome/components/waveshare_epaper/waveshare_213v3.cpp +9 -3
- esphome/components/waveshare_epaper/waveshare_epaper.cpp +1155 -44
- esphome/components/waveshare_epaper/waveshare_epaper.h +208 -7
- esphome/components/web_server/web_server.cpp +28 -6
- esphome/components/weikai/weikai.h +2 -0
- esphome/components/wifi/__init__.py +6 -6
- esphome/components/wifi/wifi_component.cpp +1 -1
- esphome/components/wifi/wifi_component_esp32_arduino.cpp +30 -1
- esphome/components/wireguard/__init__.py +2 -2
- esphome/components/xl9535/xl9535.h +2 -0
- esphome/components/xxtea/__init__.py +3 -0
- esphome/components/xxtea/xxtea.cpp +46 -0
- esphome/components/xxtea/xxtea.h +26 -0
- esphome/components/yashima/yashima.cpp +2 -1
- esphome/config.py +9 -5
- esphome/config_validation.py +55 -17
- esphome/const.py +7 -10
- esphome/core/__init__.py +6 -13
- esphome/core/base_automation.h +1 -0
- esphome/core/config.py +59 -72
- esphome/core/defines.h +9 -1
- esphome/core/gpio.h +7 -0
- esphome/core/helpers.cpp +19 -15
- esphome/core/helpers.h +57 -8
- esphome/core/log.h +9 -7
- esphome/cpp_generator.py +2 -2
- esphome/dashboard/web_server.py +1 -1
- esphome/espota2.py +3 -2
- esphome/loader.py +12 -4
- esphome/log.py +5 -7
- esphome/yaml_util.py +2 -2
- {esphome-2024.12.3.dist-info → esphome-2025.2.0.dist-info}/METADATA +14 -9
- {esphome-2024.12.3.dist-info → esphome-2025.2.0.dist-info}/RECORD +349 -300
- esphome/components/custom/binary_sensor/custom_binary_sensor.cpp +0 -16
- esphome/components/custom/binary_sensor/custom_binary_sensor.h +0 -26
- esphome/components/custom/climate/custom_climate.h +0 -22
- esphome/components/custom/cover/custom_cover.h +0 -21
- esphome/components/custom/light/custom_light_output.h +0 -24
- esphome/components/custom/output/custom_output.h +0 -37
- esphome/components/custom/sensor/custom_sensor.cpp +0 -16
- esphome/components/custom/sensor/custom_sensor.h +0 -24
- esphome/components/custom/switch/custom_switch.cpp +0 -16
- esphome/components/custom/switch/custom_switch.h +0 -24
- esphome/components/custom/text_sensor/custom_text_sensor.cpp +0 -16
- esphome/components/custom/text_sensor/custom_text_sensor.h +0 -26
- esphome/components/custom_component/custom_component.h +0 -28
- esphome/components/esp32_ble_server/ble_2901.cpp +0 -18
- esphome/components/esp32_ble_server/ble_2901.h +0 -19
- esphome/components/resistance_sampler/__init__.py +0 -6
- esphome/components/resistance_sampler/resistance_sampler.h +0 -10
- esphome/components/uptime/{sensor.py → sensor/__init__.py} +3 -3
- /esphome/components/uptime/{uptime_seconds_sensor.cpp → sensor/uptime_seconds_sensor.cpp} +0 -0
- /esphome/components/uptime/{uptime_seconds_sensor.h → sensor/uptime_seconds_sensor.h} +0 -0
- /esphome/components/uptime/{uptime_timestamp_sensor.cpp → sensor/uptime_timestamp_sensor.cpp} +0 -0
- /esphome/components/uptime/{uptime_timestamp_sensor.h → sensor/uptime_timestamp_sensor.h} +0 -0
- {esphome-2024.12.3.dist-info → esphome-2025.2.0.dist-info}/LICENSE +0 -0
- {esphome-2024.12.3.dist-info → esphome-2025.2.0.dist-info}/WHEEL +0 -0
- {esphome-2024.12.3.dist-info → esphome-2025.2.0.dist-info}/entry_points.txt +0 -0
- {esphome-2024.12.3.dist-info → esphome-2025.2.0.dist-info}/top_level.txt +0 -0
@@ -7,8 +7,10 @@ from .defines import (
|
|
7
7
|
CONF_ALIGN_TO,
|
8
8
|
CONF_X,
|
9
9
|
CONF_Y,
|
10
|
+
DIRECTIONS,
|
10
11
|
LV_EVENT_MAP,
|
11
12
|
LV_EVENT_TRIGGERS,
|
13
|
+
SWIPE_TRIGGERS,
|
12
14
|
literal,
|
13
15
|
)
|
14
16
|
from .lvcode import (
|
@@ -23,7 +25,7 @@ from .lvcode import (
|
|
23
25
|
lvgl_static,
|
24
26
|
)
|
25
27
|
from .types import LV_EVENT
|
26
|
-
from .widgets import widget_map
|
28
|
+
from .widgets import LvScrActType, get_scr_act, widget_map
|
27
29
|
|
28
30
|
|
29
31
|
async def generate_triggers():
|
@@ -33,6 +35,9 @@ async def generate_triggers():
|
|
33
35
|
"""
|
34
36
|
|
35
37
|
for w in widget_map.values():
|
38
|
+
if isinstance(w.type, LvScrActType):
|
39
|
+
w = get_scr_act(w.var)
|
40
|
+
|
36
41
|
if w.config:
|
37
42
|
for event, conf in {
|
38
43
|
event: conf
|
@@ -43,6 +48,24 @@ async def generate_triggers():
|
|
43
48
|
w.add_flag("LV_OBJ_FLAG_CLICKABLE")
|
44
49
|
event = literal("LV_EVENT_" + LV_EVENT_MAP[event[3:].upper()])
|
45
50
|
await add_trigger(conf, w, event)
|
51
|
+
|
52
|
+
for event, conf in {
|
53
|
+
event: conf
|
54
|
+
for event, conf in w.config.items()
|
55
|
+
if event in SWIPE_TRIGGERS
|
56
|
+
}.items():
|
57
|
+
conf = conf[0]
|
58
|
+
dir = event[9:].upper()
|
59
|
+
dir = {"UP": "TOP", "DOWN": "BOTTOM"}.get(dir, dir)
|
60
|
+
dir = DIRECTIONS.mapper(dir)
|
61
|
+
w.clear_flag("LV_OBJ_FLAG_SCROLLABLE")
|
62
|
+
selected = literal(
|
63
|
+
f"lv_indev_get_gesture_dir(lv_indev_get_act()) == {dir}"
|
64
|
+
)
|
65
|
+
await add_trigger(
|
66
|
+
conf, w, literal("LV_EVENT_GESTURE"), is_selected=selected
|
67
|
+
)
|
68
|
+
|
46
69
|
for conf in w.config.get(CONF_ON_VALUE, ()):
|
47
70
|
await add_trigger(
|
48
71
|
conf,
|
@@ -61,13 +84,14 @@ async def generate_triggers():
|
|
61
84
|
lv.obj_align_to(w.obj, target, align, x, y)
|
62
85
|
|
63
86
|
|
64
|
-
async def add_trigger(conf, w, *events):
|
87
|
+
async def add_trigger(conf, w, *events, is_selected=None):
|
88
|
+
is_selected = is_selected or w.is_selected()
|
65
89
|
tid = conf[CONF_TRIGGER_ID]
|
66
90
|
trigger = cg.new_Pvariable(tid)
|
67
91
|
args = w.get_args() + [(lv_event_t_ptr, "event")]
|
68
92
|
value = w.get_values()
|
69
93
|
await automation.build_automation(trigger, args, conf)
|
70
94
|
async with LambdaContext(EVENT_ARG, where=tid) as context:
|
71
|
-
with LvConditional(
|
95
|
+
with LvConditional(is_selected):
|
72
96
|
lv_add(trigger.trigger(*value, literal("event")))
|
73
97
|
lv_add(lvgl_static.add_event_cb(w.obj, await context.get_lambda(), *events))
|
@@ -37,7 +37,7 @@ DROPDOWN_BASE_SCHEMA = cv.Schema(
|
|
37
37
|
cv.Exclusive(CONF_SELECTED_INDEX, CONF_SELECTED_TEXT): lv_int,
|
38
38
|
cv.Exclusive(CONF_SELECTED_TEXT, CONF_SELECTED_TEXT): lv_text,
|
39
39
|
cv.Optional(CONF_DIR, default="BOTTOM"): DIRECTIONS.one_of,
|
40
|
-
cv.Optional(CONF_DROPDOWN_LIST): part_schema(dropdown_list_spec),
|
40
|
+
cv.Optional(CONF_DROPDOWN_LIST): part_schema(dropdown_list_spec.parts),
|
41
41
|
}
|
42
42
|
)
|
43
43
|
|
@@ -16,6 +16,11 @@ KEYBOARD_SCHEMA = {
|
|
16
16
|
cv.Optional(CONF_TEXTAREA): cv.use_id(lv_textarea_t),
|
17
17
|
}
|
18
18
|
|
19
|
+
KEYBOARD_MODIFY_SCHEMA = {
|
20
|
+
cv.Optional(CONF_MODE): KEYBOARD_MODES.one_of,
|
21
|
+
cv.Optional(CONF_TEXTAREA): cv.use_id(lv_textarea_t),
|
22
|
+
}
|
23
|
+
|
19
24
|
lv_keyboard_t = LvType(
|
20
25
|
"LvKeyboardType",
|
21
26
|
parents=(KeyProvider, LvCompound),
|
@@ -32,6 +37,7 @@ class KeyboardType(WidgetType):
|
|
32
37
|
lv_keyboard_t,
|
33
38
|
(CONF_MAIN, CONF_ITEMS),
|
34
39
|
KEYBOARD_SCHEMA,
|
40
|
+
modify_schema=KEYBOARD_MODIFY_SCHEMA,
|
35
41
|
)
|
36
42
|
|
37
43
|
def get_uses(self):
|
@@ -41,7 +47,8 @@ class KeyboardType(WidgetType):
|
|
41
47
|
lvgl_components_required.add("KEY_LISTENER")
|
42
48
|
lvgl_components_required.add(CONF_KEYBOARD)
|
43
49
|
add_lv_use("btnmatrix")
|
44
|
-
|
50
|
+
if mode := config.get(CONF_MODE):
|
51
|
+
await w.set_property(CONF_MODE, await KEYBOARD_MODES.process(mode))
|
45
52
|
if ta := await get_widgets(config, CONF_TEXTAREA):
|
46
53
|
await w.set_property(CONF_TEXTAREA, ta[0].obj)
|
47
54
|
|
@@ -27,7 +27,7 @@ from ..defines import (
|
|
27
27
|
CONF_START_VALUE,
|
28
28
|
CONF_TICKS,
|
29
29
|
)
|
30
|
-
from ..helpers import add_lv_use
|
30
|
+
from ..helpers import add_lv_use, lvgl_components_required
|
31
31
|
from ..lv_validation import (
|
32
32
|
angle,
|
33
33
|
get_end_value,
|
@@ -182,6 +182,7 @@ class MeterType(WidgetType):
|
|
182
182
|
async def to_code(self, w: Widget, config):
|
183
183
|
"""For a meter object, create and set parameters"""
|
184
184
|
|
185
|
+
lvgl_components_required.add(CONF_METER)
|
185
186
|
var = w.obj
|
186
187
|
for scale_conf in config.get(CONF_SCALES, ()):
|
187
188
|
rotation = 90 + (360 - scale_conf[CONF_ANGLE_RANGE]) / 2
|
@@ -51,7 +51,7 @@ MSGBOX_SCHEMA = container_schema(
|
|
51
51
|
cv.Required(CONF_TITLE): STYLED_TEXT_SCHEMA,
|
52
52
|
cv.Optional(CONF_BODY, default=""): STYLED_TEXT_SCHEMA,
|
53
53
|
cv.Optional(CONF_BUTTONS): cv.ensure_list(BUTTONMATRIX_BUTTON_SCHEMA),
|
54
|
-
cv.Optional(CONF_BUTTON_STYLE): part_schema(buttonmatrix_spec),
|
54
|
+
cv.Optional(CONF_BUTTON_STYLE): part_schema(buttonmatrix_spec.parts),
|
55
55
|
cv.Optional(CONF_CLOSE_BUTTON, default=True): lv_bool,
|
56
56
|
cv.GenerateID(CONF_BUTTON_TEXT_LIST_ID): cv.declare_id(char_ptr),
|
57
57
|
}
|
@@ -1,9 +1,5 @@
|
|
1
|
-
from esphome import automation
|
2
|
-
|
3
|
-
from ..automation import update_to_code
|
4
1
|
from ..defines import CONF_MAIN, CONF_OBJ, CONF_SCROLLBAR
|
5
|
-
from ..
|
6
|
-
from ..types import ObjUpdateAction, WidgetType, lv_obj_t
|
2
|
+
from ..types import WidgetType, lv_obj_t
|
7
3
|
|
8
4
|
|
9
5
|
class ObjType(WidgetType):
|
@@ -21,10 +17,3 @@ class ObjType(WidgetType):
|
|
21
17
|
|
22
18
|
|
23
19
|
obj_spec = ObjType()
|
24
|
-
|
25
|
-
|
26
|
-
@automation.register_action(
|
27
|
-
"lvgl.widget.update", ObjUpdateAction, create_modify_schema(obj_spec)
|
28
|
-
)
|
29
|
-
async def obj_update_to_code(config, action_id, template_arg, args):
|
30
|
-
return await update_to_code(config, action_id, template_arg, args)
|
@@ -2,6 +2,7 @@ from esphome import automation, codegen as cg
|
|
2
2
|
from esphome.automation import Trigger
|
3
3
|
import esphome.config_validation as cv
|
4
4
|
from esphome.const import CONF_ID, CONF_PAGES, CONF_TIME, CONF_TRIGGER_ID
|
5
|
+
from esphome.cpp_generator import MockObj, TemplateArguments
|
5
6
|
|
6
7
|
from ..defines import (
|
7
8
|
CONF_ANIMATION,
|
@@ -17,18 +18,28 @@ from ..lvcode import (
|
|
17
18
|
EVENT_ARG,
|
18
19
|
LVGL_COMP_ARG,
|
19
20
|
LambdaContext,
|
21
|
+
ReturnStatement,
|
20
22
|
add_line_marks,
|
21
23
|
lv_add,
|
22
24
|
lvgl_comp,
|
23
25
|
lvgl_static,
|
24
26
|
)
|
25
27
|
from ..schemas import LVGL_SCHEMA
|
26
|
-
from ..types import LvglAction, lv_page_t
|
27
|
-
from . import
|
28
|
+
from ..types import LvglAction, LvglCondition, lv_page_t
|
29
|
+
from . import (
|
30
|
+
Widget,
|
31
|
+
WidgetType,
|
32
|
+
add_widgets,
|
33
|
+
get_widgets,
|
34
|
+
set_obj_properties,
|
35
|
+
wait_for_widgets,
|
36
|
+
)
|
28
37
|
|
29
38
|
CONF_ON_LOAD = "on_load"
|
30
39
|
CONF_ON_UNLOAD = "on_unload"
|
31
40
|
|
41
|
+
PAGE_ARG = "_page"
|
42
|
+
|
32
43
|
PAGE_SCHEMA = cv.Schema(
|
33
44
|
{
|
34
45
|
cv.Optional(CONF_SKIP, default=False): lv_bool,
|
@@ -86,6 +97,30 @@ async def page_next_to_code(config, action_id, template_arg, args):
|
|
86
97
|
return var
|
87
98
|
|
88
99
|
|
100
|
+
@automation.register_condition(
|
101
|
+
"lvgl.page.is_showing",
|
102
|
+
LvglCondition,
|
103
|
+
cv.maybe_simple_value(
|
104
|
+
cv.Schema({cv.Required(CONF_ID): cv.use_id(lv_page_t)}),
|
105
|
+
key=CONF_ID,
|
106
|
+
),
|
107
|
+
)
|
108
|
+
async def page_is_showing_to_code(config, condition_id, template_arg, args):
|
109
|
+
await wait_for_widgets()
|
110
|
+
page = await cg.get_variable(config[CONF_ID])
|
111
|
+
async with LambdaContext(
|
112
|
+
[(lv_page_t.operator("ptr"), PAGE_ARG)], return_type=cg.bool_
|
113
|
+
) as context:
|
114
|
+
lv_add(ReturnStatement(MockObj(PAGE_ARG, "->").is_showing()))
|
115
|
+
var = cg.new_Pvariable(
|
116
|
+
condition_id,
|
117
|
+
TemplateArguments(lv_page_t, *template_arg),
|
118
|
+
await context.get_lambda(),
|
119
|
+
)
|
120
|
+
await cg.register_parented(var, page)
|
121
|
+
return var
|
122
|
+
|
123
|
+
|
89
124
|
@automation.register_action(
|
90
125
|
"lvgl.page.previous",
|
91
126
|
LvglAction,
|
@@ -38,7 +38,7 @@ TABVIEW_SCHEMA = cv.Schema(
|
|
38
38
|
},
|
39
39
|
)
|
40
40
|
),
|
41
|
-
cv.Optional(CONF_TAB_STYLE): part_schema(buttonmatrix_spec),
|
41
|
+
cv.Optional(CONF_TAB_STYLE): part_schema(buttonmatrix_spec.parts),
|
42
42
|
cv.Optional(CONF_POSITION, default="top"): DIRECTIONS.one_of,
|
43
43
|
cv.Optional(CONF_SIZE, default="10%"): size,
|
44
44
|
}
|
@@ -83,6 +83,8 @@ class MAX6956GPIOPin : public GPIOPin {
|
|
83
83
|
void set_inverted(bool inverted) { inverted_ = inverted; }
|
84
84
|
void set_flags(gpio::Flags flags) { flags_ = flags; }
|
85
85
|
|
86
|
+
gpio::Flags get_flags() const override { return this->flags_; }
|
87
|
+
|
86
88
|
protected:
|
87
89
|
MAX6956 *parent_;
|
88
90
|
uint8_t pin_;
|
@@ -61,6 +61,8 @@ class MCP23016GPIOPin : public GPIOPin {
|
|
61
61
|
void set_inverted(bool inverted) { inverted_ = inverted; }
|
62
62
|
void set_flags(gpio::Flags flags) { flags_ = flags; }
|
63
63
|
|
64
|
+
gpio::Flags get_flags() const override { return this->flags_; }
|
65
|
+
|
64
66
|
protected:
|
65
67
|
MCP23016 *parent_;
|
66
68
|
uint8_t pin_;
|
@@ -43,6 +43,8 @@ class MCP23XXXGPIOPin : public GPIOPin {
|
|
43
43
|
void set_flags(gpio::Flags flags) { flags_ = flags; }
|
44
44
|
void set_interrupt_mode(MCP23XXXInterruptMode interrupt_mode) { interrupt_mode_ = interrupt_mode; }
|
45
45
|
|
46
|
+
gpio::Flags get_flags() const override { return this->flags_; }
|
47
|
+
|
46
48
|
protected:
|
47
49
|
MCP23XXXBase *parent_;
|
48
50
|
uint8_t pin_;
|
@@ -1,5 +1,4 @@
|
|
1
1
|
from esphome import automation
|
2
|
-
from esphome.automation import maybe_simple_id
|
3
2
|
import esphome.codegen as cg
|
4
3
|
import esphome.config_validation as cv
|
5
4
|
from esphome.const import (
|
@@ -21,6 +20,16 @@ media_player_ns = cg.esphome_ns.namespace("media_player")
|
|
21
20
|
|
22
21
|
MediaPlayer = media_player_ns.class_("MediaPlayer")
|
23
22
|
|
23
|
+
MediaPlayerSupportedFormat = media_player_ns.struct("MediaPlayerSupportedFormat")
|
24
|
+
|
25
|
+
MediaPlayerFormatPurpose = media_player_ns.enum(
|
26
|
+
"MediaPlayerFormatPurpose", is_class=True
|
27
|
+
)
|
28
|
+
MEDIA_PLAYER_FORMAT_PURPOSE_ENUM = {
|
29
|
+
"default": MediaPlayerFormatPurpose.PURPOSE_DEFAULT,
|
30
|
+
"announcement": MediaPlayerFormatPurpose.PURPOSE_ANNOUNCEMENT,
|
31
|
+
}
|
32
|
+
|
24
33
|
|
25
34
|
PlayAction = media_player_ns.class_(
|
26
35
|
"PlayAction", automation.Action, cg.Parented.template(MediaPlayer)
|
@@ -47,7 +56,7 @@ VolumeSetAction = media_player_ns.class_(
|
|
47
56
|
"VolumeSetAction", automation.Action, cg.Parented.template(MediaPlayer)
|
48
57
|
)
|
49
58
|
|
50
|
-
|
59
|
+
CONF_ANNOUNCEMENT = "announcement"
|
51
60
|
CONF_ON_PLAY = "on_play"
|
52
61
|
CONF_ON_PAUSE = "on_pause"
|
53
62
|
CONF_ON_ANNOUNCEMENT = "on_announcement"
|
@@ -125,7 +134,16 @@ MEDIA_PLAYER_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(
|
|
125
134
|
)
|
126
135
|
|
127
136
|
|
128
|
-
MEDIA_PLAYER_ACTION_SCHEMA =
|
137
|
+
MEDIA_PLAYER_ACTION_SCHEMA = cv.Schema(
|
138
|
+
{
|
139
|
+
cv.GenerateID(): cv.use_id(MediaPlayer),
|
140
|
+
cv.Optional(CONF_ANNOUNCEMENT, default=False): cv.templatable(cv.boolean),
|
141
|
+
}
|
142
|
+
)
|
143
|
+
|
144
|
+
MEDIA_PLAYER_CONDITION_SCHEMA = automation.maybe_simple_id(
|
145
|
+
{cv.GenerateID(): cv.use_id(MediaPlayer)}
|
146
|
+
)
|
129
147
|
|
130
148
|
|
131
149
|
@automation.register_action(
|
@@ -135,6 +153,7 @@ MEDIA_PLAYER_ACTION_SCHEMA = maybe_simple_id({cv.GenerateID(): cv.use_id(MediaPl
|
|
135
153
|
{
|
136
154
|
cv.GenerateID(): cv.use_id(MediaPlayer),
|
137
155
|
cv.Required(CONF_MEDIA_URL): cv.templatable(cv.url),
|
156
|
+
cv.Optional(CONF_ANNOUNCEMENT, default=False): cv.templatable(cv.boolean),
|
138
157
|
},
|
139
158
|
key=CONF_MEDIA_URL,
|
140
159
|
),
|
@@ -143,7 +162,9 @@ async def media_player_play_media_action(config, action_id, template_arg, args):
|
|
143
162
|
var = cg.new_Pvariable(action_id, template_arg)
|
144
163
|
await cg.register_parented(var, config[CONF_ID])
|
145
164
|
media_url = await cg.templatable(config[CONF_MEDIA_URL], args, cg.std_string)
|
165
|
+
announcement = await cg.templatable(config[CONF_ANNOUNCEMENT], args, cg.bool_)
|
146
166
|
cg.add(var.set_media_url(media_url))
|
167
|
+
cg.add(var.set_announcement(announcement))
|
147
168
|
return var
|
148
169
|
|
149
170
|
|
@@ -161,19 +182,27 @@ async def media_player_play_media_action(config, action_id, template_arg, args):
|
|
161
182
|
@automation.register_action(
|
162
183
|
"media_player.volume_down", VolumeDownAction, MEDIA_PLAYER_ACTION_SCHEMA
|
163
184
|
)
|
185
|
+
async def media_player_action(config, action_id, template_arg, args):
|
186
|
+
var = cg.new_Pvariable(action_id, template_arg)
|
187
|
+
await cg.register_parented(var, config[CONF_ID])
|
188
|
+
announcement = await cg.templatable(config[CONF_ANNOUNCEMENT], args, cg.bool_)
|
189
|
+
cg.add(var.set_announcement(announcement))
|
190
|
+
return var
|
191
|
+
|
192
|
+
|
164
193
|
@automation.register_condition(
|
165
|
-
"media_player.is_idle", IsIdleCondition,
|
194
|
+
"media_player.is_idle", IsIdleCondition, MEDIA_PLAYER_CONDITION_SCHEMA
|
166
195
|
)
|
167
196
|
@automation.register_condition(
|
168
|
-
"media_player.is_paused", IsPausedCondition,
|
197
|
+
"media_player.is_paused", IsPausedCondition, MEDIA_PLAYER_CONDITION_SCHEMA
|
169
198
|
)
|
170
199
|
@automation.register_condition(
|
171
|
-
"media_player.is_playing", IsPlayingCondition,
|
200
|
+
"media_player.is_playing", IsPlayingCondition, MEDIA_PLAYER_CONDITION_SCHEMA
|
172
201
|
)
|
173
202
|
@automation.register_condition(
|
174
|
-
"media_player.is_announcing", IsAnnouncingCondition,
|
203
|
+
"media_player.is_announcing", IsAnnouncingCondition, MEDIA_PLAYER_CONDITION_SCHEMA
|
175
204
|
)
|
176
|
-
async def
|
205
|
+
async def media_player_condition(config, action_id, template_arg, args):
|
177
206
|
var = cg.new_Pvariable(action_id, template_arg)
|
178
207
|
await cg.register_parented(var, config[CONF_ID])
|
179
208
|
return var
|
@@ -10,7 +10,10 @@ namespace media_player {
|
|
10
10
|
template<MediaPlayerCommand Command, typename... Ts>
|
11
11
|
class MediaPlayerCommandAction : public Action<Ts...>, public Parented<MediaPlayer> {
|
12
12
|
public:
|
13
|
-
|
13
|
+
TEMPLATABLE_VALUE(bool, announcement);
|
14
|
+
void play(Ts... x) override {
|
15
|
+
this->parent_->make_call().set_command(Command).set_announcement(this->announcement_.value(x...)).perform();
|
16
|
+
}
|
14
17
|
};
|
15
18
|
|
16
19
|
template<typename... Ts>
|
@@ -28,7 +31,13 @@ using VolumeDownAction = MediaPlayerCommandAction<MediaPlayerCommand::MEDIA_PLAY
|
|
28
31
|
|
29
32
|
template<typename... Ts> class PlayMediaAction : public Action<Ts...>, public Parented<MediaPlayer> {
|
30
33
|
TEMPLATABLE_VALUE(std::string, media_url)
|
31
|
-
|
34
|
+
TEMPLATABLE_VALUE(bool, announcement)
|
35
|
+
void play(Ts... x) override {
|
36
|
+
this->parent_->make_call()
|
37
|
+
.set_media_url(this->media_url_.value(x...))
|
38
|
+
.set_announcement(this->announcement_.value(x...))
|
39
|
+
.perform();
|
40
|
+
}
|
32
41
|
};
|
33
42
|
|
34
43
|
template<typename... Ts> class VolumeSetAction : public Action<Ts...>, public Parented<MediaPlayer> {
|
@@ -41,6 +41,14 @@ const char *media_player_command_to_string(MediaPlayerCommand command) {
|
|
41
41
|
return "VOLUME_UP";
|
42
42
|
case MEDIA_PLAYER_COMMAND_VOLUME_DOWN:
|
43
43
|
return "VOLUME_DOWN";
|
44
|
+
case MEDIA_PLAYER_COMMAND_ENQUEUE:
|
45
|
+
return "ENQUEUE";
|
46
|
+
case MEDIA_PLAYER_COMMAND_REPEAT_ONE:
|
47
|
+
return "REPEAT_ONE";
|
48
|
+
case MEDIA_PLAYER_COMMAND_REPEAT_OFF:
|
49
|
+
return "REPEAT_OFF";
|
50
|
+
case MEDIA_PLAYER_COMMAND_CLEAR_PLAYLIST:
|
51
|
+
return "CLEAR_PLAYLIST";
|
44
52
|
default:
|
45
53
|
return "UNKNOWN";
|
46
54
|
}
|
@@ -24,6 +24,10 @@ enum MediaPlayerCommand : uint8_t {
|
|
24
24
|
MEDIA_PLAYER_COMMAND_TOGGLE = 5,
|
25
25
|
MEDIA_PLAYER_COMMAND_VOLUME_UP = 6,
|
26
26
|
MEDIA_PLAYER_COMMAND_VOLUME_DOWN = 7,
|
27
|
+
MEDIA_PLAYER_COMMAND_ENQUEUE = 8,
|
28
|
+
MEDIA_PLAYER_COMMAND_REPEAT_ONE = 9,
|
29
|
+
MEDIA_PLAYER_COMMAND_REPEAT_OFF = 10,
|
30
|
+
MEDIA_PLAYER_COMMAND_CLEAR_PLAYLIST = 11,
|
27
31
|
};
|
28
32
|
const char *media_player_command_to_string(MediaPlayerCommand command);
|
29
33
|
|
@@ -72,10 +76,10 @@ class MediaPlayerCall {
|
|
72
76
|
|
73
77
|
void perform();
|
74
78
|
|
75
|
-
const optional<MediaPlayerCommand> &get_command() const { return command_; }
|
76
|
-
const optional<std::string> &get_media_url() const { return media_url_; }
|
77
|
-
const optional<float> &get_volume() const { return volume_; }
|
78
|
-
const optional<bool> &get_announcement() const { return announcement_; }
|
79
|
+
const optional<MediaPlayerCommand> &get_command() const { return this->command_; }
|
80
|
+
const optional<std::string> &get_media_url() const { return this->media_url_; }
|
81
|
+
const optional<float> &get_volume() const { return this->volume_; }
|
82
|
+
const optional<bool> &get_announcement() const { return this->announcement_; }
|
79
83
|
|
80
84
|
protected:
|
81
85
|
void validate_();
|
@@ -11,15 +11,17 @@ void MicroNovaSwitch::write_state(bool state) {
|
|
11
11
|
if (this->micronova_->get_current_stove_state() == 0) {
|
12
12
|
this->micronova_->write_address(this->memory_location_, this->memory_address_, this->memory_data_on_);
|
13
13
|
this->publish_state(true);
|
14
|
-
} else
|
14
|
+
} else {
|
15
15
|
ESP_LOGW(TAG, "Unable to turn stove on, invalid state: %d", micronova_->get_current_stove_state());
|
16
|
+
}
|
16
17
|
} else {
|
17
18
|
// don't send power-off when status is Off or Final cleaning
|
18
19
|
if (this->micronova_->get_current_stove_state() != 0 && micronova_->get_current_stove_state() != 6) {
|
19
20
|
this->micronova_->write_address(this->memory_location_, this->memory_address_, this->memory_data_off_);
|
20
21
|
this->publish_state(false);
|
21
|
-
} else
|
22
|
+
} else {
|
22
23
|
ESP_LOGW(TAG, "Unable to turn stove off, invalid state: %d", micronova_->get_current_stove_state());
|
24
|
+
}
|
23
25
|
}
|
24
26
|
this->micronova_->update();
|
25
27
|
break;
|
@@ -19,10 +19,12 @@ template<typename... Ts> class MideaActionBase : public Action<Ts...> {
|
|
19
19
|
|
20
20
|
template<typename... Ts> class FollowMeAction : public MideaActionBase<Ts...> {
|
21
21
|
TEMPLATABLE_VALUE(float, temperature)
|
22
|
+
TEMPLATABLE_VALUE(bool, use_fahrenheit)
|
22
23
|
TEMPLATABLE_VALUE(bool, beeper)
|
23
24
|
|
24
25
|
void play(Ts... x) override {
|
25
|
-
this->parent_->do_follow_me(this->temperature_.value(x...), this->
|
26
|
+
this->parent_->do_follow_me(this->temperature_.value(x...), this->use_fahrenheit_.value(x...),
|
27
|
+
this->beeper_.value(x...));
|
26
28
|
}
|
27
29
|
};
|
28
30
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
#ifdef USE_ARDUINO
|
2
2
|
|
3
3
|
#include "esphome/core/log.h"
|
4
|
+
#include "esphome/core/helpers.h"
|
4
5
|
#include "air_conditioner.h"
|
5
6
|
#include "ac_adapter.h"
|
6
7
|
#include <cmath>
|
@@ -121,7 +122,7 @@ void AirConditioner::dump_config() {
|
|
121
122
|
|
122
123
|
/* ACTIONS */
|
123
124
|
|
124
|
-
void AirConditioner::do_follow_me(float temperature, bool beeper) {
|
125
|
+
void AirConditioner::do_follow_me(float temperature, bool use_fahrenheit, bool beeper) {
|
125
126
|
#ifdef USE_REMOTE_TRANSMITTER
|
126
127
|
// Check if temperature is finite (not NaN or infinite)
|
127
128
|
if (!std::isfinite(temperature)) {
|
@@ -131,13 +132,14 @@ void AirConditioner::do_follow_me(float temperature, bool beeper) {
|
|
131
132
|
|
132
133
|
// Round and convert temperature to long, then clamp and convert it to uint8_t
|
133
134
|
uint8_t temp_uint8 =
|
134
|
-
static_cast<uint8_t>(std::
|
135
|
+
static_cast<uint8_t>(esphome::clamp<long>(std::lroundf(temperature), 0L, static_cast<long>(UINT8_MAX)));
|
135
136
|
|
136
|
-
|
137
|
-
|
137
|
+
char temp_symbol = use_fahrenheit ? 'F' : 'C';
|
138
|
+
ESP_LOGD(Constants::TAG, "Follow me action called with temperature: %.5f °%c, rounded to: %u °%c", temperature,
|
139
|
+
temp_symbol, temp_uint8, temp_symbol);
|
138
140
|
|
139
141
|
// Create and transmit the data
|
140
|
-
IrFollowMeData data(temp_uint8, beeper);
|
142
|
+
IrFollowMeData data(temp_uint8, use_fahrenheit, beeper);
|
141
143
|
this->transmitter_.transmit(data);
|
142
144
|
#else
|
143
145
|
ESP_LOGW(Constants::TAG, "Action needs remote_transmitter component");
|
@@ -32,7 +32,7 @@ class AirConditioner : public ApplianceBase<dudanov::midea::ac::AirConditioner>,
|
|
32
32
|
/* ### ACTIONS ### */
|
33
33
|
/* ############### */
|
34
34
|
|
35
|
-
void do_follow_me(float temperature, bool beeper = false);
|
35
|
+
void do_follow_me(float temperature, bool use_fahrenheit, bool beeper = false);
|
36
36
|
void do_display_toggle();
|
37
37
|
void do_swing_step();
|
38
38
|
void do_beeper_on() { this->set_beeper_feedback(true); }
|
@@ -18,6 +18,7 @@ from esphome.const import (
|
|
18
18
|
CONF_SUPPORTED_SWING_MODES,
|
19
19
|
CONF_TIMEOUT,
|
20
20
|
CONF_TEMPERATURE,
|
21
|
+
CONF_USE_FAHRENHEIT,
|
21
22
|
DEVICE_CLASS_POWER,
|
22
23
|
DEVICE_CLASS_TEMPERATURE,
|
23
24
|
DEVICE_CLASS_HUMIDITY,
|
@@ -172,11 +173,10 @@ MIDEA_ACTION_BASE_SCHEMA = cv.Schema(
|
|
172
173
|
)
|
173
174
|
|
174
175
|
# FollowMe action
|
175
|
-
MIDEA_FOLLOW_ME_MIN = 0
|
176
|
-
MIDEA_FOLLOW_ME_MAX = 37
|
177
176
|
MIDEA_FOLLOW_ME_SCHEMA = cv.Schema(
|
178
177
|
{
|
179
178
|
cv.Required(CONF_TEMPERATURE): cv.templatable(cv.temperature),
|
179
|
+
cv.Optional(CONF_USE_FAHRENHEIT, default=False): cv.templatable(cv.boolean),
|
180
180
|
cv.Optional(CONF_BEEPER, default=False): cv.templatable(cv.boolean),
|
181
181
|
}
|
182
182
|
)
|
@@ -186,6 +186,8 @@ MIDEA_FOLLOW_ME_SCHEMA = cv.Schema(
|
|
186
186
|
async def follow_me_to_code(var, config, args):
|
187
187
|
template_ = await cg.templatable(config[CONF_BEEPER], args, cg.bool_)
|
188
188
|
cg.add(var.set_beeper(template_))
|
189
|
+
template_ = await cg.templatable(config[CONF_USE_FAHRENHEIT], args, cg.bool_)
|
190
|
+
cg.add(var.set_use_fahrenheit(template_))
|
189
191
|
template_ = await cg.templatable(config[CONF_TEMPERATURE], args, cg.float_)
|
190
192
|
cg.add(var.set_temperature(template_))
|
191
193
|
|
@@ -16,22 +16,53 @@ class IrFollowMeData : public IrData {
|
|
16
16
|
IrFollowMeData() : IrData({MIDEA_TYPE_FOLLOW_ME, 0x82, 0x48, 0x7F, 0x1F}) {}
|
17
17
|
// Copy from Base
|
18
18
|
IrFollowMeData(const IrData &data) : IrData(data) {}
|
19
|
-
// Direct from temperature and beeper values
|
19
|
+
// Direct from temperature in celsius and beeper values
|
20
20
|
IrFollowMeData(uint8_t temp, bool beeper = false) : IrFollowMeData() {
|
21
|
-
this->set_temp(temp);
|
21
|
+
this->set_temp(temp, false);
|
22
|
+
this->set_beeper(beeper);
|
23
|
+
}
|
24
|
+
// Direct from temperature, fahrenheit and beeper values
|
25
|
+
IrFollowMeData(uint8_t temp, bool fahrenheit, bool beeper) : IrFollowMeData() {
|
26
|
+
this->set_temp(temp, fahrenheit);
|
22
27
|
this->set_beeper(beeper);
|
23
28
|
}
|
24
29
|
|
25
30
|
/* TEMPERATURE */
|
26
|
-
uint8_t temp() const {
|
27
|
-
|
31
|
+
uint8_t temp() const {
|
32
|
+
if (this->fahrenheit()) {
|
33
|
+
return this->get_value_(4) + 31;
|
34
|
+
}
|
35
|
+
return this->get_value_(4) - 1;
|
36
|
+
}
|
37
|
+
void set_temp(uint8_t val, bool fahrenheit = false) {
|
38
|
+
this->set_fahrenheit(fahrenheit);
|
39
|
+
if (this->fahrenheit()) {
|
40
|
+
// see https://github.com/esphome/feature-requests/issues/1627#issuecomment-1365639966
|
41
|
+
val = esphome::clamp<uint8_t>(val, MIN_TEMP_F, MAX_TEMP_F) - 31;
|
42
|
+
} else {
|
43
|
+
val = esphome::clamp<uint8_t>(val, MIN_TEMP_C, MAX_TEMP_C) + 1;
|
44
|
+
}
|
45
|
+
this->set_value_(4, val);
|
46
|
+
}
|
28
47
|
|
29
48
|
/* BEEPER */
|
30
49
|
bool beeper() const { return this->get_value_(3, 128); }
|
31
50
|
void set_beeper(bool val) { this->set_mask_(3, val, 128); }
|
32
51
|
|
52
|
+
/* FAHRENHEIT */
|
53
|
+
bool fahrenheit() const { return this->get_value_(2, 32); }
|
54
|
+
void set_fahrenheit(bool val) { this->set_mask_(2, val, 32); }
|
55
|
+
|
33
56
|
protected:
|
34
|
-
static const uint8_t
|
57
|
+
static const uint8_t MIN_TEMP_C = 0;
|
58
|
+
static const uint8_t MAX_TEMP_C = 37;
|
59
|
+
|
60
|
+
// see
|
61
|
+
// https://github.com/crankyoldgit/IRremoteESP8266/blob/9bdf8abcb465268c5409db99dc83a26df64c7445/src/ir_Midea.h#L116
|
62
|
+
static const uint8_t MIN_TEMP_F = 32;
|
63
|
+
// see
|
64
|
+
// https://github.com/crankyoldgit/IRremoteESP8266/blob/9bdf8abcb465268c5409db99dc83a26df64c7445/src/ir_Midea.h#L117
|
65
|
+
static const uint8_t MAX_TEMP_F = 99;
|
35
66
|
};
|
36
67
|
|
37
68
|
class IrSpecialData : public IrData {
|
File without changes
|