esphome 2025.9.3__py3-none-any.whl → 2025.10.0b2__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 +94 -31
- esphome/address_cache.py +142 -0
- esphome/automation.py +130 -32
- esphome/build_gen/platformio.py +1 -3
- esphome/codegen.py +1 -0
- esphome/components/animation/animation.cpp +2 -2
- esphome/components/api/__init__.py +166 -3
- esphome/components/api/api_connection.cpp +84 -41
- esphome/components/api/api_connection.h +22 -16
- esphome/components/api/api_frame_helper.cpp +33 -19
- esphome/components/api/api_frame_helper.h +19 -4
- esphome/components/api/api_frame_helper_noise.cpp +41 -53
- esphome/components/api/api_frame_helper_noise.h +1 -1
- esphome/components/api/api_frame_helper_plaintext.cpp +22 -31
- esphome/components/api/api_frame_helper_plaintext.h +1 -1
- esphome/components/api/api_pb2.cpp +189 -15
- esphome/components/api/api_pb2.h +132 -20
- esphome/components/api/api_pb2_dump.cpp +97 -9
- esphome/components/api/api_pb2_service.cpp +118 -160
- esphome/components/api/api_pb2_service.h +31 -3
- esphome/components/api/api_server.cpp +68 -10
- esphome/components/api/api_server.h +32 -4
- esphome/components/api/custom_api_device.h +8 -8
- esphome/components/api/homeassistant_service.h +123 -6
- esphome/components/api/proto.h +6 -2
- esphome/components/api/user_services.h +2 -2
- esphome/components/as7341/sensor.py +1 -1
- esphome/components/audio/__init__.py +1 -1
- esphome/components/audio/audio.cpp +1 -1
- esphome/components/audio/audio_decoder.cpp +9 -9
- esphome/components/bl0906/bl0906.cpp +2 -2
- esphome/components/bl0942/bl0942.cpp +2 -2
- esphome/components/ble_client/__init__.py +1 -1
- esphome/components/bluetooth_proxy/__init__.py +4 -30
- esphome/components/bluetooth_proxy/bluetooth_connection.cpp +11 -4
- esphome/components/bluetooth_proxy/bluetooth_connection.h +2 -2
- esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +2 -2
- esphome/components/camera_encoder/__init__.py +2 -4
- esphome/components/camera_encoder/esp32_camera_jpeg_encoder.cpp +4 -2
- esphome/components/camera_encoder/esp32_camera_jpeg_encoder.h +3 -1
- esphome/components/canbus/canbus.cpp +7 -5
- esphome/components/canbus/canbus.h +7 -7
- esphome/components/captive_portal/__init__.py +18 -1
- esphome/components/captive_portal/captive_portal.cpp +40 -46
- esphome/components/captive_portal/captive_portal.h +20 -22
- esphome/components/captive_portal/dns_server_esp32_idf.cpp +205 -0
- esphome/components/captive_portal/dns_server_esp32_idf.h +27 -0
- esphome/components/ccs811/ccs811.cpp +1 -1
- esphome/components/climate/climate.cpp +10 -7
- esphome/components/cm1106/cm1106.cpp +1 -1
- esphome/components/copy/lock/copy_lock.cpp +1 -1
- esphome/components/cover/cover.cpp +1 -0
- esphome/components/daikin_arc/daikin_arc.cpp +19 -12
- esphome/components/dashboard_import/dashboard_import.cpp +1 -1
- esphome/components/dashboard_import/dashboard_import.h +1 -1
- esphome/components/deep_sleep/__init__.py +9 -2
- esphome/components/deep_sleep/deep_sleep_component.h +11 -9
- esphome/components/deep_sleep/deep_sleep_esp32.cpp +51 -27
- esphome/components/ektf2232/touchscreen/__init__.py +8 -5
- esphome/components/ektf2232/touchscreen/ektf2232.cpp +4 -4
- esphome/components/ektf2232/touchscreen/ektf2232.h +2 -2
- esphome/components/epaper_spi/__init__.py +1 -0
- esphome/components/epaper_spi/display.py +80 -0
- esphome/components/epaper_spi/epaper_spi.cpp +227 -0
- esphome/components/epaper_spi/epaper_spi.h +93 -0
- esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.cpp +42 -0
- esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.h +45 -0
- esphome/components/epaper_spi/epaper_spi_spectra_e6.cpp +135 -0
- esphome/components/epaper_spi/epaper_spi_spectra_e6.h +23 -0
- esphome/components/es7210/es7210.cpp +3 -3
- esphome/components/esp32/__init__.py +256 -340
- esphome/components/esp32/boards.py +81 -0
- esphome/components/esp32/preferences.cpp +23 -17
- esphome/components/esp32_ble/__init__.py +167 -44
- esphome/components/esp32_ble/ble.cpp +47 -3
- esphome/components/esp32_ble/ble.h +18 -0
- esphome/components/esp32_ble/ble_advertising.cpp +7 -3
- esphome/components/esp32_ble/ble_advertising.h +4 -0
- esphome/components/esp32_ble/ble_uuid.cpp +16 -42
- esphome/components/esp32_ble_beacon/__init__.py +3 -4
- esphome/components/esp32_ble_beacon/esp32_ble_beacon.cpp +0 -4
- esphome/components/esp32_ble_client/ble_client_base.cpp +14 -12
- esphome/components/esp32_ble_server/__init__.py +28 -14
- esphome/components/esp32_ble_server/ble_characteristic.cpp +67 -57
- esphome/components/esp32_ble_server/ble_characteristic.h +27 -16
- esphome/components/esp32_ble_server/ble_descriptor.cpp +4 -3
- esphome/components/esp32_ble_server/ble_descriptor.h +13 -9
- esphome/components/esp32_ble_server/ble_server.cpp +59 -24
- esphome/components/esp32_ble_server/ble_server.h +38 -20
- esphome/components/esp32_ble_server/ble_server_automations.cpp +49 -33
- esphome/components/esp32_ble_server/ble_server_automations.h +39 -24
- esphome/components/esp32_ble_tracker/__init__.py +25 -80
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +2 -8
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +0 -3
- esphome/components/esp32_camera/__init__.py +1 -3
- esphome/components/esp32_can/esp32_can.cpp +22 -4
- esphome/components/esp32_can/esp32_can.h +3 -0
- esphome/components/esp32_hosted/__init__.py +2 -1
- esphome/components/esp32_improv/esp32_improv_component.cpp +135 -65
- esphome/components/esp32_improv/esp32_improv_component.h +7 -1
- esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
- esphome/components/esp8266/__init__.py +3 -3
- esphome/components/esphome/ota/__init__.py +21 -2
- esphome/components/esphome/ota/ota_esphome.cpp +456 -146
- esphome/components/esphome/ota/ota_esphome.h +49 -2
- esphome/components/ethernet/__init__.py +39 -22
- esphome/components/ethernet/ethernet_component.cpp +28 -5
- esphome/components/ethernet/ethernet_component.h +5 -1
- esphome/components/external_components/__init__.py +8 -6
- esphome/components/fingerprint_grow/fingerprint_grow.cpp +1 -1
- esphome/components/fingerprint_grow/fingerprint_grow.h +2 -1
- esphome/components/font/__init__.py +5 -5
- esphome/components/graph/graph.cpp +1 -1
- esphome/components/graphical_display_menu/graphical_display_menu.cpp +3 -2
- esphome/components/haier/hon_climate.cpp +2 -2
- esphome/components/haier/hon_climate.h +1 -1
- esphome/components/hdc1080/hdc1080.cpp +42 -34
- esphome/components/hdc1080/hdc1080.h +1 -3
- esphome/components/homeassistant/number/homeassistant_number.cpp +2 -2
- esphome/components/homeassistant/switch/homeassistant_switch.cpp +2 -2
- esphome/components/http_request/__init__.py +3 -3
- esphome/components/htu21d/htu21d.cpp +13 -18
- esphome/components/htu21d/htu21d.h +1 -1
- esphome/components/i2s_audio/__init__.py +1 -2
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +1 -1
- esphome/components/ili9xxx/ili9xxx_display.cpp +2 -2
- esphome/components/improv_serial/improv_serial_component.cpp +12 -15
- esphome/components/improv_serial/improv_serial_component.h +6 -8
- esphome/components/json/json_util.cpp +42 -44
- esphome/components/json/json_util.h +57 -0
- esphome/components/kamstrup_kmp/kamstrup_kmp.cpp +2 -2
- esphome/components/key_collector/key_collector.h +4 -4
- esphome/components/libretiny/__init__.py +6 -6
- esphome/components/libretiny/preferences.cpp +23 -16
- esphome/components/light/light_call.cpp +98 -120
- esphome/components/light/light_call.h +17 -7
- esphome/components/lm75b/__init__.py +0 -0
- esphome/components/lm75b/lm75b.cpp +39 -0
- esphome/components/lm75b/lm75b.h +19 -0
- esphome/components/lm75b/sensor.py +34 -0
- esphome/components/lock/lock.h +12 -6
- esphome/components/logger/__init__.py +15 -27
- esphome/components/logger/logger.cpp +10 -20
- esphome/components/logger/logger.h +105 -62
- esphome/components/logger/logger_esp32.cpp +0 -48
- esphome/components/logger/logger_zephyr.cpp +2 -3
- esphome/components/logger/select/logger_level_select.cpp +6 -7
- esphome/components/logger/select/logger_level_select.h +7 -0
- esphome/components/ltr501/ltr501.cpp +7 -6
- esphome/components/ltr_als_ps/ltr_als_ps.cpp +7 -6
- esphome/components/matrix_keypad/matrix_keypad.h +4 -4
- esphome/components/max7219digit/max7219digit.cpp +1 -1
- esphome/components/mcp23xxx_base/mcp23xxx_base.h +3 -3
- esphome/components/mcp2515/mcp2515.cpp +31 -3
- esphome/components/mcp2515/mcp2515_defs.h +3 -1
- esphome/components/md5/md5.cpp +0 -26
- esphome/components/md5/md5.h +10 -20
- esphome/components/mdns/__init__.py +93 -19
- esphome/components/mdns/mdns_component.cpp +57 -94
- esphome/components/mdns/mdns_component.h +35 -11
- esphome/components/mdns/mdns_esp32.cpp +7 -13
- esphome/components/mdns/mdns_esp8266.cpp +7 -7
- esphome/components/mdns/mdns_libretiny.cpp +3 -4
- esphome/components/mdns/mdns_rp2040.cpp +3 -4
- esphome/components/mipi/__init__.py +1 -5
- esphome/components/mipi_spi/display.py +24 -8
- esphome/components/mipi_spi/mipi_spi.h +3 -3
- esphome/components/mixer/speaker/mixer_speaker.cpp +3 -3
- esphome/components/mmc5603/mmc5603.cpp +3 -3
- esphome/components/modbus/modbus.cpp +27 -13
- esphome/components/modbus/modbus.h +5 -3
- esphome/components/modbus/modbus_definitions.h +86 -0
- esphome/components/modbus_controller/__init__.py +29 -1
- esphome/components/modbus_controller/const.py +4 -0
- esphome/components/modbus_controller/modbus_controller.cpp +38 -13
- esphome/components/modbus_controller/modbus_controller.h +18 -29
- esphome/components/mpr121/mpr121.cpp +41 -42
- esphome/components/mpr121/mpr121.h +0 -1
- esphome/components/nau7802/nau7802.cpp +2 -2
- esphome/components/network/__init__.py +7 -3
- esphome/components/nextion/display.py +4 -4
- esphome/components/nextion/nextion.cpp +8 -8
- esphome/components/number/__init__.py +2 -0
- esphome/components/number/number_call.cpp +23 -12
- esphome/components/number/number_call.h +5 -0
- esphome/components/online_image/bmp_image.cpp +2 -1
- esphome/components/online_image/jpeg_image.cpp +4 -2
- esphome/components/opentherm/opentherm.cpp +5 -5
- esphome/components/opentherm/opentherm.h +3 -3
- esphome/components/openthread/openthread.cpp +11 -10
- esphome/components/openthread/openthread.h +0 -1
- esphome/components/ota/ota_backend.h +1 -0
- esphome/components/packages/__init__.py +10 -8
- esphome/components/packet_transport/packet_transport.cpp +2 -0
- esphome/components/pid/pid_controller.cpp +1 -1
- esphome/components/prometheus/prometheus_handler.cpp +239 -239
- esphome/components/psram/__init__.py +30 -28
- esphome/components/qmc5883l/qmc5883l.cpp +15 -0
- esphome/components/qmc5883l/qmc5883l.h +3 -0
- esphome/components/qmc5883l/sensor.py +31 -12
- esphome/components/remote_base/gobox_protocol.cpp +3 -3
- esphome/components/remote_receiver/__init__.py +14 -2
- esphome/components/remote_receiver/{remote_receiver_esp8266.cpp → remote_receiver.cpp} +2 -2
- esphome/components/remote_receiver/remote_receiver.h +4 -0
- esphome/components/remote_receiver/remote_receiver_esp32.cpp +18 -1
- esphome/components/remote_transmitter/__init__.py +2 -2
- esphome/components/remote_transmitter/remote_transmitter.cpp +103 -0
- esphome/components/rp2040/__init__.py +11 -11
- esphome/components/rtttl/rtttl.cpp +2 -2
- esphome/components/scd30/sensor.py +1 -1
- esphome/components/script/__init__.py +1 -1
- esphome/components/script/script.h +7 -7
- esphome/components/select/select.cpp +5 -4
- esphome/components/select/select_call.cpp +1 -1
- esphome/components/sensirion_common/i2c_sensirion.cpp +2 -1
- esphome/components/sensor/__init__.py +2 -0
- esphome/components/sha256/__init__.py +22 -0
- esphome/components/sha256/sha256.cpp +116 -0
- esphome/components/sha256/sha256.h +60 -0
- esphome/components/socket/lwip_raw_tcp_impl.cpp +34 -6
- esphome/components/sonoff_d1/sonoff_d1.cpp +1 -1
- esphome/components/spi/__init__.py +0 -3
- esphome/components/split_buffer/__init__.py +5 -0
- esphome/components/split_buffer/split_buffer.cpp +133 -0
- esphome/components/split_buffer/split_buffer.h +40 -0
- esphome/components/sps30/sps30.cpp +14 -10
- esphome/components/sps30/sps30.h +2 -0
- esphome/components/st7567_i2c/st7567_i2c.cpp +3 -1
- esphome/components/st7789v/st7789v.cpp +3 -2
- esphome/components/statsd/statsd.cpp +1 -1
- esphome/components/substitutions/__init__.py +3 -1
- esphome/components/substitutions/jinja.py +13 -3
- esphome/components/sx126x/__init__.py +16 -0
- esphome/components/sx126x/sx126x.cpp +15 -1
- esphome/components/sx126x/sx126x.h +9 -1
- esphome/components/sx126x/sx126x_reg.h +2 -0
- esphome/components/text_sensor/text_sensor.cpp +16 -0
- esphome/components/text_sensor/text_sensor.h +3 -10
- esphome/components/tormatic/tormatic_cover.cpp +1 -1
- esphome/components/tuya/select/tuya_select.cpp +1 -1
- esphome/components/tuya/tuya.cpp +29 -4
- esphome/components/uart/__init__.py +37 -27
- esphome/components/uart/uart.h +6 -0
- esphome/components/uart/uart_component.cpp +8 -0
- esphome/components/uart/uart_component.h +28 -0
- esphome/components/uart/uart_component_esp_idf.cpp +64 -10
- esphome/components/uart/uart_component_esp_idf.h +5 -2
- esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +1 -1
- esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.cpp +1 -1
- esphome/components/uponor_smatrix/uponor_smatrix.cpp +3 -3
- esphome/components/usb_host/__init__.py +12 -2
- esphome/components/usb_host/usb_host.h +89 -14
- esphome/components/usb_host/usb_host_client.cpp +157 -22
- esphome/components/usb_host/usb_host_component.cpp +1 -1
- esphome/components/usb_uart/__init__.py +0 -1
- esphome/components/usb_uart/ch34x.cpp +4 -4
- esphome/components/usb_uart/cp210x.cpp +3 -3
- esphome/components/usb_uart/usb_uart.cpp +88 -32
- esphome/components/usb_uart/usb_uart.h +30 -6
- esphome/components/valve/valve.cpp +1 -0
- esphome/components/veml7700/veml7700.cpp +7 -6
- esphome/components/version/version_text_sensor.cpp +2 -1
- esphome/components/voice_assistant/voice_assistant.cpp +3 -2
- esphome/components/waveshare_epaper/waveshare_epaper.cpp +4 -4
- esphome/components/web_server/list_entities.cpp +3 -4
- esphome/components/web_server/list_entities.h +8 -10
- esphome/components/web_server/ota/__init__.py +1 -1
- esphome/components/web_server/ota/ota_web_server.cpp +9 -3
- esphome/components/web_server/web_server.cpp +509 -404
- esphome/components/web_server/web_server.h +5 -6
- esphome/components/web_server/web_server_v1.cpp +21 -19
- esphome/components/web_server_base/__init__.py +5 -2
- esphome/components/web_server_base/web_server_base.h +27 -7
- esphome/components/web_server_idf/__init__.py +1 -1
- esphome/components/web_server_idf/multipart.cpp +2 -2
- esphome/components/web_server_idf/multipart.h +2 -2
- esphome/components/web_server_idf/utils.cpp +2 -2
- esphome/components/web_server_idf/utils.h +2 -2
- esphome/components/web_server_idf/web_server_idf.cpp +118 -26
- esphome/components/web_server_idf/web_server_idf.h +12 -10
- esphome/components/wifi/__init__.py +13 -11
- esphome/components/wifi/wifi_component.cpp +74 -56
- esphome/components/wifi/wifi_component.h +4 -4
- esphome/components/wifi/wifi_component_esp8266.cpp +1 -1
- esphome/components/wifi/wifi_component_esp_idf.cpp +24 -4
- esphome/components/wireguard/__init__.py +1 -1
- esphome/components/wts01/__init__.py +0 -0
- esphome/components/wts01/sensor.py +41 -0
- esphome/components/wts01/wts01.cpp +91 -0
- esphome/components/wts01/wts01.h +27 -0
- esphome/components/zephyr/__init__.py +5 -5
- esphome/components/zwave_proxy/__init__.py +43 -0
- esphome/components/zwave_proxy/zwave_proxy.cpp +346 -0
- esphome/components/zwave_proxy/zwave_proxy.h +93 -0
- esphome/config.py +79 -24
- esphome/config_validation.py +13 -15
- esphome/const.py +9 -2
- esphome/core/__init__.py +33 -22
- esphome/core/component.cpp +28 -18
- esphome/core/component_iterator.h +2 -1
- esphome/core/config.py +15 -15
- esphome/core/defines.h +21 -0
- esphome/core/entity_helpers.py +9 -6
- esphome/core/hash_base.h +56 -0
- esphome/core/helpers.cpp +19 -3
- esphome/core/helpers.h +26 -0
- esphome/core/scheduler.cpp +5 -21
- esphome/core/scheduler.h +19 -8
- esphome/core/string_ref.h +1 -1
- esphome/core/time.cpp +5 -5
- esphome/cpp_generator.py +4 -29
- esphome/dashboard/const.py +21 -4
- esphome/dashboard/core.py +10 -8
- esphome/dashboard/dns.py +15 -0
- esphome/dashboard/entries.py +15 -21
- esphome/dashboard/models.py +76 -0
- esphome/dashboard/settings.py +7 -7
- esphome/dashboard/status/mdns.py +46 -2
- esphome/dashboard/web_server.py +367 -93
- esphome/espota2.py +112 -32
- esphome/external_files.py +6 -7
- esphome/git.py +8 -0
- esphome/helpers.py +124 -77
- esphome/loader.py +8 -9
- esphome/pins.py +2 -2
- esphome/platformio_api.py +56 -18
- esphome/storage_json.py +26 -21
- esphome/types.py +30 -2
- esphome/util.py +32 -16
- esphome/vscode.py +8 -8
- esphome/wizard.py +10 -10
- esphome/writer.py +50 -15
- esphome/yaml_util.py +37 -31
- esphome/zeroconf.py +12 -3
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/METADATA +12 -12
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/RECORD +340 -320
- esphome/components/event_emitter/__init__.py +0 -5
- esphome/components/event_emitter/event_emitter.cpp +0 -14
- esphome/components/event_emitter/event_emitter.h +0 -63
- esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -125
- esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +0 -107
- esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +0 -110
- esphome/components/uart/uart_component_esp32_arduino.cpp +0 -214
- esphome/components/uart/uart_component_esp32_arduino.h +0 -60
- esphome/components/wifi/wifi_component_esp32_arduino.cpp +0 -860
- esphome/core/string_ref.cpp +0 -12
- esphome/dashboard/util/file.py +0 -63
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/WHEEL +0 -0
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/entry_points.txt +0 -0
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/top_level.txt +0 -0
@@ -1,9 +1,10 @@
|
|
1
|
+
from ast import literal_eval
|
1
2
|
import logging
|
2
3
|
import math
|
3
4
|
import re
|
4
5
|
|
5
6
|
import jinja2 as jinja
|
6
|
-
from jinja2.
|
7
|
+
from jinja2.sandbox import SandboxedEnvironment
|
7
8
|
|
8
9
|
TemplateError = jinja.TemplateError
|
9
10
|
TemplateSyntaxError = jinja.TemplateSyntaxError
|
@@ -70,7 +71,7 @@ class Jinja:
|
|
70
71
|
"""
|
71
72
|
|
72
73
|
def __init__(self, context_vars):
|
73
|
-
self.env =
|
74
|
+
self.env = SandboxedEnvironment(
|
74
75
|
trim_blocks=True,
|
75
76
|
lstrip_blocks=True,
|
76
77
|
block_start_string="<%",
|
@@ -90,6 +91,15 @@ class Jinja:
|
|
90
91
|
**SAFE_GLOBAL_FUNCTIONS,
|
91
92
|
}
|
92
93
|
|
94
|
+
def safe_eval(self, expr):
|
95
|
+
try:
|
96
|
+
result = literal_eval(expr)
|
97
|
+
if not isinstance(result, str):
|
98
|
+
return result
|
99
|
+
except (ValueError, SyntaxError, MemoryError, TypeError):
|
100
|
+
pass
|
101
|
+
return expr
|
102
|
+
|
93
103
|
def expand(self, content_str):
|
94
104
|
"""
|
95
105
|
Renders a string that may contain Jinja expressions or statements
|
@@ -106,7 +116,7 @@ class Jinja:
|
|
106
116
|
override_vars = content_str.upvalues
|
107
117
|
try:
|
108
118
|
template = self.env.from_string(content_str)
|
109
|
-
result = template.render(override_vars)
|
119
|
+
result = self.safe_eval(template.render(override_vars))
|
110
120
|
if isinstance(result, Undefined):
|
111
121
|
# This happens when the expression is simply an undefined variable. Jinja does not
|
112
122
|
# raise an exception, instead we get "Undefined".
|
@@ -15,6 +15,10 @@ CONF_BANDWIDTH = "bandwidth"
|
|
15
15
|
CONF_BITRATE = "bitrate"
|
16
16
|
CONF_CODING_RATE = "coding_rate"
|
17
17
|
CONF_CRC_ENABLE = "crc_enable"
|
18
|
+
CONF_CRC_INVERTED = "crc_inverted"
|
19
|
+
CONF_CRC_SIZE = "crc_size"
|
20
|
+
CONF_CRC_POLYNOMIAL = "crc_polynomial"
|
21
|
+
CONF_CRC_INITIAL = "crc_initial"
|
18
22
|
CONF_DEVIATION = "deviation"
|
19
23
|
CONF_DIO1_PIN = "dio1_pin"
|
20
24
|
CONF_HW_VERSION = "hw_version"
|
@@ -188,6 +192,14 @@ CONFIG_SCHEMA = (
|
|
188
192
|
cv.Required(CONF_BUSY_PIN): pins.internal_gpio_input_pin_schema,
|
189
193
|
cv.Optional(CONF_CODING_RATE, default="CR_4_5"): cv.enum(CODING_RATE),
|
190
194
|
cv.Optional(CONF_CRC_ENABLE, default=False): cv.boolean,
|
195
|
+
cv.Optional(CONF_CRC_INVERTED, default=True): cv.boolean,
|
196
|
+
cv.Optional(CONF_CRC_SIZE, default=2): cv.int_range(min=1, max=2),
|
197
|
+
cv.Optional(CONF_CRC_POLYNOMIAL, default=0x1021): cv.All(
|
198
|
+
cv.hex_int, cv.Range(min=0, max=0xFFFF)
|
199
|
+
),
|
200
|
+
cv.Optional(CONF_CRC_INITIAL, default=0x1D0F): cv.All(
|
201
|
+
cv.hex_int, cv.Range(min=0, max=0xFFFF)
|
202
|
+
),
|
191
203
|
cv.Optional(CONF_DEVIATION, default=5000): cv.int_range(min=0, max=100000),
|
192
204
|
cv.Required(CONF_DIO1_PIN): pins.internal_gpio_input_pin_schema,
|
193
205
|
cv.Required(CONF_FREQUENCY): cv.int_range(min=137000000, max=1020000000),
|
@@ -251,6 +263,10 @@ async def to_code(config):
|
|
251
263
|
cg.add(var.set_shaping(config[CONF_SHAPING]))
|
252
264
|
cg.add(var.set_bitrate(config[CONF_BITRATE]))
|
253
265
|
cg.add(var.set_crc_enable(config[CONF_CRC_ENABLE]))
|
266
|
+
cg.add(var.set_crc_inverted(config[CONF_CRC_INVERTED]))
|
267
|
+
cg.add(var.set_crc_size(config[CONF_CRC_SIZE]))
|
268
|
+
cg.add(var.set_crc_polynomial(config[CONF_CRC_POLYNOMIAL]))
|
269
|
+
cg.add(var.set_crc_initial(config[CONF_CRC_INITIAL]))
|
254
270
|
cg.add(var.set_payload_length(config[CONF_PAYLOAD_LENGTH]))
|
255
271
|
cg.add(var.set_preamble_size(config[CONF_PREAMBLE_SIZE]))
|
256
272
|
cg.add(var.set_preamble_detect(config[CONF_PREAMBLE_DETECT]))
|
@@ -235,6 +235,16 @@ void SX126x::configure() {
|
|
235
235
|
buf[7] = (fdev >> 0) & 0xFF;
|
236
236
|
this->write_opcode_(RADIO_SET_MODULATIONPARAMS, buf, 8);
|
237
237
|
|
238
|
+
// set crc params
|
239
|
+
if (this->crc_enable_) {
|
240
|
+
buf[0] = this->crc_initial_ >> 8;
|
241
|
+
buf[1] = this->crc_initial_ & 0xFF;
|
242
|
+
this->write_register_(REG_CRC_INITIAL, buf, 2);
|
243
|
+
buf[0] = this->crc_polynomial_ >> 8;
|
244
|
+
buf[1] = this->crc_polynomial_ & 0xFF;
|
245
|
+
this->write_register_(REG_CRC_POLYNOMIAL, buf, 2);
|
246
|
+
}
|
247
|
+
|
238
248
|
// set packet params and sync word
|
239
249
|
this->set_packet_params_(this->get_max_packet_size());
|
240
250
|
if (!this->sync_value_.empty()) {
|
@@ -276,7 +286,11 @@ void SX126x::set_packet_params_(uint8_t payload_length) {
|
|
276
286
|
buf[4] = 0x00;
|
277
287
|
buf[5] = (this->payload_length_ > 0) ? 0x00 : 0x01;
|
278
288
|
buf[6] = payload_length;
|
279
|
-
|
289
|
+
if (this->crc_enable_) {
|
290
|
+
buf[7] = (this->crc_inverted_ ? 0x04 : 0x00) + (this->crc_size_ & 0x02);
|
291
|
+
} else {
|
292
|
+
buf[7] = 0x01;
|
293
|
+
}
|
280
294
|
buf[8] = 0x00;
|
281
295
|
this->write_opcode_(RADIO_SET_PACKETPARAMS, buf, 9);
|
282
296
|
}
|
@@ -67,6 +67,10 @@ class SX126x : public Component,
|
|
67
67
|
void set_busy_pin(InternalGPIOPin *busy_pin) { this->busy_pin_ = busy_pin; }
|
68
68
|
void set_coding_rate(uint8_t coding_rate) { this->coding_rate_ = coding_rate; }
|
69
69
|
void set_crc_enable(bool crc_enable) { this->crc_enable_ = crc_enable; }
|
70
|
+
void set_crc_inverted(bool crc_inverted) { this->crc_inverted_ = crc_inverted; }
|
71
|
+
void set_crc_size(uint8_t crc_size) { this->crc_size_ = crc_size; }
|
72
|
+
void set_crc_polynomial(uint16_t crc_polynomial) { this->crc_polynomial_ = crc_polynomial; }
|
73
|
+
void set_crc_initial(uint16_t crc_initial) { this->crc_initial_ = crc_initial; }
|
70
74
|
void set_deviation(uint32_t deviation) { this->deviation_ = deviation; }
|
71
75
|
void set_dio1_pin(InternalGPIOPin *dio1_pin) { this->dio1_pin_ = dio1_pin; }
|
72
76
|
void set_frequency(uint32_t frequency) { this->frequency_ = frequency; }
|
@@ -118,6 +122,11 @@ class SX126x : public Component,
|
|
118
122
|
char version_[16];
|
119
123
|
SX126xBw bandwidth_{SX126X_BW_125000};
|
120
124
|
uint32_t bitrate_{0};
|
125
|
+
bool crc_enable_{false};
|
126
|
+
bool crc_inverted_{false};
|
127
|
+
uint8_t crc_size_{0};
|
128
|
+
uint16_t crc_polynomial_{0};
|
129
|
+
uint16_t crc_initial_{0};
|
121
130
|
uint32_t deviation_{0};
|
122
131
|
uint32_t frequency_{0};
|
123
132
|
uint32_t payload_length_{0};
|
@@ -131,7 +140,6 @@ class SX126x : public Component,
|
|
131
140
|
uint8_t shaping_{0};
|
132
141
|
uint8_t spreading_factor_{0};
|
133
142
|
int8_t pa_power_{0};
|
134
|
-
bool crc_enable_{false};
|
135
143
|
bool rx_start_{false};
|
136
144
|
bool rf_switch_{false};
|
137
145
|
};
|
@@ -6,6 +6,22 @@ namespace text_sensor {
|
|
6
6
|
|
7
7
|
static const char *const TAG = "text_sensor";
|
8
8
|
|
9
|
+
void log_text_sensor(const char *tag, const char *prefix, const char *type, TextSensor *obj) {
|
10
|
+
if (obj == nullptr) {
|
11
|
+
return;
|
12
|
+
}
|
13
|
+
|
14
|
+
ESP_LOGCONFIG(tag, "%s%s '%s'", prefix, type, obj->get_name().c_str());
|
15
|
+
|
16
|
+
if (!obj->get_device_class_ref().empty()) {
|
17
|
+
ESP_LOGCONFIG(tag, "%s Device Class: '%s'", prefix, obj->get_device_class_ref().c_str());
|
18
|
+
}
|
19
|
+
|
20
|
+
if (!obj->get_icon_ref().empty()) {
|
21
|
+
ESP_LOGCONFIG(tag, "%s Icon: '%s'", prefix, obj->get_icon_ref().c_str());
|
22
|
+
}
|
23
|
+
}
|
24
|
+
|
9
25
|
void TextSensor::publish_state(const std::string &state) {
|
10
26
|
this->raw_state = state;
|
11
27
|
if (this->raw_callback_) {
|
@@ -11,16 +11,9 @@
|
|
11
11
|
namespace esphome {
|
12
12
|
namespace text_sensor {
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
if (!(obj)->get_device_class_ref().empty()) { \
|
18
|
-
ESP_LOGCONFIG(TAG, "%s Device Class: '%s'", prefix, (obj)->get_device_class_ref().c_str()); \
|
19
|
-
} \
|
20
|
-
if (!(obj)->get_icon_ref().empty()) { \
|
21
|
-
ESP_LOGCONFIG(TAG, "%s Icon: '%s'", prefix, (obj)->get_icon_ref().c_str()); \
|
22
|
-
} \
|
23
|
-
}
|
14
|
+
void log_text_sensor(const char *tag, const char *prefix, const char *type, TextSensor *obj);
|
15
|
+
|
16
|
+
#define LOG_TEXT_SENSOR(prefix, type, obj) log_text_sensor(TAG, prefix, LOG_STR_LITERAL(type), obj)
|
24
17
|
|
25
18
|
#define SUB_TEXT_SENSOR(name) \
|
26
19
|
protected: \
|
@@ -251,7 +251,7 @@ void Tormatic::stop_at_target_() {
|
|
251
251
|
// Read a GateStatus from the unit. The unit only sends messages in response to
|
252
252
|
// status requests or commands, so a message needs to be sent first.
|
253
253
|
optional<GateStatus> Tormatic::read_gate_status_() {
|
254
|
-
if (this->available() < sizeof(MessageHeader)) {
|
254
|
+
if (this->available() < static_cast<int>(sizeof(MessageHeader))) {
|
255
255
|
return {};
|
256
256
|
}
|
257
257
|
|
@@ -50,7 +50,7 @@ void TuyaSelect::dump_config() {
|
|
50
50
|
" Options are:",
|
51
51
|
this->select_id_, this->is_int_ ? "int" : "enum");
|
52
52
|
auto options = this->traits.get_options();
|
53
|
-
for (
|
53
|
+
for (size_t i = 0; i < this->mappings_.size(); i++) {
|
54
54
|
ESP_LOGCONFIG(TAG, " %i: %s", this->mappings_.at(i), options.at(i).c_str());
|
55
55
|
}
|
56
56
|
}
|
esphome/components/tuya/tuya.cpp
CHANGED
@@ -215,12 +215,37 @@ void Tuya::handle_command_(uint8_t command, uint8_t version, const uint8_t *buff
|
|
215
215
|
this->send_empty_command_(TuyaCommandType::DATAPOINT_QUERY);
|
216
216
|
}
|
217
217
|
break;
|
218
|
-
case TuyaCommandType::WIFI_RESET:
|
219
|
-
ESP_LOGE(TAG, "WIFI_RESET is not handled");
|
220
|
-
break;
|
221
218
|
case TuyaCommandType::WIFI_SELECT:
|
222
|
-
|
219
|
+
case TuyaCommandType::WIFI_RESET: {
|
220
|
+
const bool is_select = (len >= 1);
|
221
|
+
// Send WIFI_SELECT ACK
|
222
|
+
TuyaCommand ack;
|
223
|
+
ack.cmd = is_select ? TuyaCommandType::WIFI_SELECT : TuyaCommandType::WIFI_RESET;
|
224
|
+
ack.payload.clear();
|
225
|
+
this->send_command_(ack);
|
226
|
+
// Establish pairing mode for correct first WIFI_STATE byte, EZ (0x00) default
|
227
|
+
uint8_t first = 0x00;
|
228
|
+
const char *mode_str = "EZ";
|
229
|
+
if (is_select && buffer[0] == 0x01) {
|
230
|
+
first = 0x01;
|
231
|
+
mode_str = "AP";
|
232
|
+
}
|
233
|
+
// Send WIFI_STATE response, MCU exits pairing mode
|
234
|
+
TuyaCommand st;
|
235
|
+
st.cmd = TuyaCommandType::WIFI_STATE;
|
236
|
+
st.payload.resize(1);
|
237
|
+
st.payload[0] = first;
|
238
|
+
this->send_command_(st);
|
239
|
+
st.payload[0] = 0x02;
|
240
|
+
this->send_command_(st);
|
241
|
+
st.payload[0] = 0x03;
|
242
|
+
this->send_command_(st);
|
243
|
+
st.payload[0] = 0x04;
|
244
|
+
this->send_command_(st);
|
245
|
+
ESP_LOGI(TAG, "%s received (%s), replied with WIFI_STATE confirming connection established",
|
246
|
+
is_select ? "WIFI_SELECT" : "WIFI_RESET", mode_str);
|
223
247
|
break;
|
248
|
+
}
|
224
249
|
case TuyaCommandType::DATAPOINT_DELIVER:
|
225
250
|
break;
|
226
251
|
case TuyaCommandType::DATAPOINT_REPORT_ASYNC:
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import math
|
1
2
|
import re
|
2
3
|
|
3
4
|
from esphome import automation, pins
|
@@ -14,9 +15,9 @@ from esphome.const import (
|
|
14
15
|
CONF_DIRECTION,
|
15
16
|
CONF_DUMMY_RECEIVER,
|
16
17
|
CONF_DUMMY_RECEIVER_ID,
|
18
|
+
CONF_FLOW_CONTROL_PIN,
|
17
19
|
CONF_ID,
|
18
20
|
CONF_INVERT,
|
19
|
-
CONF_INVERTED,
|
20
21
|
CONF_LAMBDA,
|
21
22
|
CONF_NUMBER,
|
22
23
|
CONF_PORT,
|
@@ -39,9 +40,6 @@ uart_ns = cg.esphome_ns.namespace("uart")
|
|
39
40
|
UARTComponent = uart_ns.class_("UARTComponent")
|
40
41
|
|
41
42
|
IDFUARTComponent = uart_ns.class_("IDFUARTComponent", UARTComponent, cg.Component)
|
42
|
-
ESP32ArduinoUARTComponent = uart_ns.class_(
|
43
|
-
"ESP32ArduinoUARTComponent", UARTComponent, cg.Component
|
44
|
-
)
|
45
43
|
ESP8266UartComponent = uart_ns.class_(
|
46
44
|
"ESP8266UartComponent", UARTComponent, cg.Component
|
47
45
|
)
|
@@ -53,7 +51,6 @@ HostUartComponent = uart_ns.class_("HostUartComponent", UARTComponent, cg.Compon
|
|
53
51
|
|
54
52
|
NATIVE_UART_CLASSES = (
|
55
53
|
str(IDFUARTComponent),
|
56
|
-
str(ESP32ArduinoUARTComponent),
|
57
54
|
str(ESP8266UartComponent),
|
58
55
|
str(RP2040UartComponent),
|
59
56
|
str(LibreTinyUARTComponent),
|
@@ -119,20 +116,6 @@ def validate_rx_pin(value):
|
|
119
116
|
return value
|
120
117
|
|
121
118
|
|
122
|
-
def validate_invert_esp32(config):
|
123
|
-
if (
|
124
|
-
CORE.is_esp32
|
125
|
-
and CORE.using_arduino
|
126
|
-
and CONF_TX_PIN in config
|
127
|
-
and CONF_RX_PIN in config
|
128
|
-
and config[CONF_TX_PIN][CONF_INVERTED] != config[CONF_RX_PIN][CONF_INVERTED]
|
129
|
-
):
|
130
|
-
raise cv.Invalid(
|
131
|
-
"Different invert values for TX and RX pin are not supported for ESP32 when using Arduino."
|
132
|
-
)
|
133
|
-
return config
|
134
|
-
|
135
|
-
|
136
119
|
def validate_host_config(config):
|
137
120
|
if CORE.is_host:
|
138
121
|
if CONF_TX_PIN in config or CONF_RX_PIN in config:
|
@@ -151,10 +134,7 @@ def _uart_declare_type(value):
|
|
151
134
|
if CORE.is_esp8266:
|
152
135
|
return cv.declare_id(ESP8266UartComponent)(value)
|
153
136
|
if CORE.is_esp32:
|
154
|
-
|
155
|
-
return cv.declare_id(ESP32ArduinoUARTComponent)(value)
|
156
|
-
if CORE.using_esp_idf:
|
157
|
-
return cv.declare_id(IDFUARTComponent)(value)
|
137
|
+
return cv.declare_id(IDFUARTComponent)(value)
|
158
138
|
if CORE.is_rp2040:
|
159
139
|
return cv.declare_id(RP2040UartComponent)(value)
|
160
140
|
if CORE.is_libretiny:
|
@@ -174,6 +154,8 @@ UART_PARITY_OPTIONS = {
|
|
174
154
|
CONF_STOP_BITS = "stop_bits"
|
175
155
|
CONF_DATA_BITS = "data_bits"
|
176
156
|
CONF_PARITY = "parity"
|
157
|
+
CONF_RX_FULL_THRESHOLD = "rx_full_threshold"
|
158
|
+
CONF_RX_TIMEOUT = "rx_timeout"
|
177
159
|
|
178
160
|
UARTDirection = uart_ns.enum("UARTDirection")
|
179
161
|
UART_DIRECTIONS = {
|
@@ -241,8 +223,17 @@ CONFIG_SCHEMA = cv.All(
|
|
241
223
|
cv.Required(CONF_BAUD_RATE): cv.int_range(min=1),
|
242
224
|
cv.Optional(CONF_TX_PIN): pins.internal_gpio_output_pin_schema,
|
243
225
|
cv.Optional(CONF_RX_PIN): validate_rx_pin,
|
226
|
+
cv.Optional(CONF_FLOW_CONTROL_PIN): cv.All(
|
227
|
+
cv.only_on_esp32, pins.internal_gpio_output_pin_schema
|
228
|
+
),
|
244
229
|
cv.Optional(CONF_PORT): cv.All(validate_port, cv.only_on(PLATFORM_HOST)),
|
245
230
|
cv.Optional(CONF_RX_BUFFER_SIZE, default=256): cv.validate_bytes,
|
231
|
+
cv.Optional(CONF_RX_FULL_THRESHOLD): cv.All(
|
232
|
+
cv.only_on_esp32, cv.validate_bytes, cv.int_range(min=1, max=120)
|
233
|
+
),
|
234
|
+
cv.SplitDefault(CONF_RX_TIMEOUT, esp32=2): cv.All(
|
235
|
+
cv.only_on_esp32, cv.validate_bytes, cv.int_range(min=0, max=92)
|
236
|
+
),
|
246
237
|
cv.Optional(CONF_STOP_BITS, default=1): cv.one_of(1, 2, int=True),
|
247
238
|
cv.Optional(CONF_DATA_BITS, default=8): cv.int_range(min=5, max=8),
|
248
239
|
cv.Optional(CONF_PARITY, default="NONE"): cv.enum(
|
@@ -255,7 +246,6 @@ CONFIG_SCHEMA = cv.All(
|
|
255
246
|
}
|
256
247
|
).extend(cv.COMPONENT_SCHEMA),
|
257
248
|
cv.has_at_least_one_key(CONF_TX_PIN, CONF_RX_PIN, CONF_PORT),
|
258
|
-
validate_invert_esp32,
|
259
249
|
validate_host_config,
|
260
250
|
)
|
261
251
|
|
@@ -298,9 +288,27 @@ async def to_code(config):
|
|
298
288
|
if CONF_RX_PIN in config:
|
299
289
|
rx_pin = await cg.gpio_pin_expression(config[CONF_RX_PIN])
|
300
290
|
cg.add(var.set_rx_pin(rx_pin))
|
291
|
+
if CONF_FLOW_CONTROL_PIN in config:
|
292
|
+
flow_control_pin = await cg.gpio_pin_expression(config[CONF_FLOW_CONTROL_PIN])
|
293
|
+
cg.add(var.set_flow_control_pin(flow_control_pin))
|
301
294
|
if CONF_PORT in config:
|
302
295
|
cg.add(var.set_name(config[CONF_PORT]))
|
303
296
|
cg.add(var.set_rx_buffer_size(config[CONF_RX_BUFFER_SIZE]))
|
297
|
+
if CORE.is_esp32:
|
298
|
+
if CONF_RX_FULL_THRESHOLD not in config:
|
299
|
+
# Calculate rx_full_threshold to be 10ms
|
300
|
+
bytelength = config[CONF_DATA_BITS] + config[CONF_STOP_BITS] + 1
|
301
|
+
if config[CONF_PARITY] != "NONE":
|
302
|
+
bytelength += 1
|
303
|
+
config[CONF_RX_FULL_THRESHOLD] = max(
|
304
|
+
1,
|
305
|
+
min(
|
306
|
+
120,
|
307
|
+
math.floor((config[CONF_BAUD_RATE] / (bytelength * 1000 / 10)) - 1),
|
308
|
+
),
|
309
|
+
)
|
310
|
+
cg.add(var.set_rx_full_threshold(config[CONF_RX_FULL_THRESHOLD]))
|
311
|
+
cg.add(var.set_rx_timeout(config[CONF_RX_TIMEOUT]))
|
304
312
|
cg.add(var.set_stop_bits(config[CONF_STOP_BITS]))
|
305
313
|
cg.add(var.set_data_bits(config[CONF_DATA_BITS]))
|
306
314
|
cg.add(var.set_parity(config[CONF_PARITY]))
|
@@ -339,7 +347,7 @@ def final_validate_device_schema(
|
|
339
347
|
|
340
348
|
def validate_pin(opt, device):
|
341
349
|
def validator(value):
|
342
|
-
if opt in device:
|
350
|
+
if opt in device and not CORE.testing_mode:
|
343
351
|
raise cv.Invalid(
|
344
352
|
f"The uart {opt} is used both by {name} and {device[opt]}, "
|
345
353
|
f"but can only be used by one. Please create a new uart bus for {name}."
|
@@ -444,8 +452,10 @@ async def uart_write_to_code(config, action_id, template_arg, args):
|
|
444
452
|
|
445
453
|
FILTER_SOURCE_FILES = filter_source_files_from_platform(
|
446
454
|
{
|
447
|
-
"
|
448
|
-
|
455
|
+
"uart_component_esp_idf.cpp": {
|
456
|
+
PlatformFramework.ESP32_IDF,
|
457
|
+
PlatformFramework.ESP32_ARDUINO,
|
458
|
+
},
|
449
459
|
"uart_component_esp8266.cpp": {PlatformFramework.ESP8266_ARDUINO},
|
450
460
|
"uart_component_host.cpp": {PlatformFramework.HOST_NATIVE},
|
451
461
|
"uart_component_rp2040.cpp": {PlatformFramework.RP2040_ARDUINO},
|
esphome/components/uart/uart.h
CHANGED
@@ -18,6 +18,12 @@ class UARTDevice {
|
|
18
18
|
|
19
19
|
void write_byte(uint8_t data) { this->parent_->write_byte(data); }
|
20
20
|
|
21
|
+
void set_rx_full_threshold(size_t rx_full_threshold) { this->parent_->set_rx_full_threshold(rx_full_threshold); }
|
22
|
+
void set_rx_full_threshold_ms(size_t time) { this->parent_->set_rx_full_threshold_ms(time); }
|
23
|
+
size_t get_rx_full_threshold() { return this->parent_->get_rx_full_threshold(); }
|
24
|
+
void set_rx_timeout(size_t rx_timeout) { this->parent_->set_rx_timeout(rx_timeout); }
|
25
|
+
size_t get_rx_timeout() { return this->parent_->get_rx_timeout(); }
|
26
|
+
|
21
27
|
void write_array(const uint8_t *data, size_t len) { this->parent_->write_array(data, len); }
|
22
28
|
void write_array(const std::vector<uint8_t> &data) { this->parent_->write_array(data); }
|
23
29
|
template<size_t N> void write_array(const std::array<uint8_t, N> &data) {
|
@@ -20,5 +20,13 @@ bool UARTComponent::check_read_timeout_(size_t len) {
|
|
20
20
|
return true;
|
21
21
|
}
|
22
22
|
|
23
|
+
void UARTComponent::set_rx_full_threshold_ms(uint8_t time) {
|
24
|
+
uint8_t bytelength = this->data_bits_ + this->stop_bits_ + 1;
|
25
|
+
if (this->parity_ != UARTParityOptions::UART_CONFIG_PARITY_NONE)
|
26
|
+
bytelength += 1;
|
27
|
+
int32_t val = clamp<int32_t>((this->baud_rate_ / (bytelength * 1000 / time)) - 1, 1, 120);
|
28
|
+
this->set_rx_full_threshold(val);
|
29
|
+
}
|
30
|
+
|
23
31
|
} // namespace uart
|
24
32
|
} // namespace esphome
|
@@ -6,6 +6,7 @@
|
|
6
6
|
#include "esphome/core/component.h"
|
7
7
|
#include "esphome/core/hal.h"
|
8
8
|
#include "esphome/core/log.h"
|
9
|
+
#include "esphome/core/helpers.h"
|
9
10
|
#ifdef USE_UART_DEBUGGER
|
10
11
|
#include "esphome/core/automation.h"
|
11
12
|
#endif
|
@@ -82,6 +83,10 @@ class UARTComponent {
|
|
82
83
|
// @param rx_pin Pointer to the internal GPIO pin used for reception.
|
83
84
|
void set_rx_pin(InternalGPIOPin *rx_pin) { this->rx_pin_ = rx_pin; }
|
84
85
|
|
86
|
+
// Sets the flow control pin for the UART bus.
|
87
|
+
// @param flow_control_pin Pointer to the internal GPIO pin used for flow control.
|
88
|
+
void set_flow_control_pin(InternalGPIOPin *flow_control_pin) { this->flow_control_pin_ = flow_control_pin; }
|
89
|
+
|
85
90
|
// Sets the size of the RX buffer.
|
86
91
|
// @param rx_buffer_size Size of the RX buffer in bytes.
|
87
92
|
void set_rx_buffer_size(size_t rx_buffer_size) { this->rx_buffer_size_ = rx_buffer_size; }
|
@@ -90,6 +95,26 @@ class UARTComponent {
|
|
90
95
|
// @return Size of the RX buffer in bytes.
|
91
96
|
size_t get_rx_buffer_size() { return this->rx_buffer_size_; }
|
92
97
|
|
98
|
+
// Sets the RX FIFO full interrupt threshold.
|
99
|
+
// @param rx_full_threshold RX full interrupt threshold in bytes.
|
100
|
+
virtual void set_rx_full_threshold(size_t rx_full_threshold) {}
|
101
|
+
|
102
|
+
// Sets the RX FIFO full interrupt threshold.
|
103
|
+
// @param time RX full interrupt threshold in ms.
|
104
|
+
void set_rx_full_threshold_ms(uint8_t time);
|
105
|
+
|
106
|
+
// Gets the RX FIFO full interrupt threshold.
|
107
|
+
// @return RX full interrupt threshold in bytes.
|
108
|
+
size_t get_rx_full_threshold() { return this->rx_full_threshold_; }
|
109
|
+
|
110
|
+
// Sets the RX timeout interrupt threshold.
|
111
|
+
// @param rx_timeout RX timeout interrupt threshold (unit: time of sending one byte).
|
112
|
+
virtual void set_rx_timeout(size_t rx_timeout) {}
|
113
|
+
|
114
|
+
// Gets the RX timeout interrupt threshold.
|
115
|
+
// @return RX timeout interrupt threshold (unit: time of sending one byte).
|
116
|
+
size_t get_rx_timeout() { return this->rx_timeout_; }
|
117
|
+
|
93
118
|
// Sets the number of stop bits used in UART communication.
|
94
119
|
// @param stop_bits Number of stop bits.
|
95
120
|
void set_stop_bits(uint8_t stop_bits) { this->stop_bits_ = stop_bits; }
|
@@ -161,7 +186,10 @@ class UARTComponent {
|
|
161
186
|
|
162
187
|
InternalGPIOPin *tx_pin_;
|
163
188
|
InternalGPIOPin *rx_pin_;
|
189
|
+
InternalGPIOPin *flow_control_pin_;
|
164
190
|
size_t rx_buffer_size_;
|
191
|
+
size_t rx_full_threshold_{1};
|
192
|
+
size_t rx_timeout_{0};
|
165
193
|
uint32_t baud_rate_;
|
166
194
|
uint8_t stop_bits_;
|
167
195
|
uint8_t data_bits_;
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#ifdef
|
1
|
+
#ifdef USE_ESP32
|
2
2
|
|
3
3
|
#include "uart_component_esp_idf.h"
|
4
4
|
#include <cinttypes>
|
@@ -90,6 +90,12 @@ void IDFUARTComponent::setup() {
|
|
90
90
|
|
91
91
|
xSemaphoreTake(this->lock_, portMAX_DELAY);
|
92
92
|
|
93
|
+
this->load_settings(false);
|
94
|
+
|
95
|
+
xSemaphoreGive(this->lock_);
|
96
|
+
}
|
97
|
+
|
98
|
+
void IDFUARTComponent::load_settings(bool dump_config) {
|
93
99
|
uart_config_t uart_config = this->get_config_();
|
94
100
|
esp_err_t err = uart_param_config(this->uart_num_, &uart_config);
|
95
101
|
if (err != ESP_OK) {
|
@@ -100,6 +106,7 @@ void IDFUARTComponent::setup() {
|
|
100
106
|
|
101
107
|
int8_t tx = this->tx_pin_ != nullptr ? this->tx_pin_->get_pin() : -1;
|
102
108
|
int8_t rx = this->rx_pin_ != nullptr ? this->rx_pin_->get_pin() : -1;
|
109
|
+
int8_t flow_control = this->flow_control_pin_ != nullptr ? this->flow_control_pin_->get_pin() : -1;
|
103
110
|
|
104
111
|
uint32_t invert = 0;
|
105
112
|
if (this->tx_pin_ != nullptr && this->tx_pin_->is_inverted())
|
@@ -114,13 +121,21 @@ void IDFUARTComponent::setup() {
|
|
114
121
|
return;
|
115
122
|
}
|
116
123
|
|
117
|
-
err = uart_set_pin(this->uart_num_, tx, rx,
|
124
|
+
err = uart_set_pin(this->uart_num_, tx, rx, flow_control, UART_PIN_NO_CHANGE);
|
118
125
|
if (err != ESP_OK) {
|
119
126
|
ESP_LOGW(TAG, "uart_set_pin failed: %s", esp_err_to_name(err));
|
120
127
|
this->mark_failed();
|
121
128
|
return;
|
122
129
|
}
|
123
130
|
|
131
|
+
if (uart_is_driver_installed(this->uart_num_)) {
|
132
|
+
uart_driver_delete(this->uart_num_);
|
133
|
+
if (err != ESP_OK) {
|
134
|
+
ESP_LOGW(TAG, "uart_driver_delete failed: %s", esp_err_to_name(err));
|
135
|
+
this->mark_failed();
|
136
|
+
return;
|
137
|
+
}
|
138
|
+
}
|
124
139
|
err = uart_driver_install(this->uart_num_, /* UART RX ring buffer size. */ this->rx_buffer_size_,
|
125
140
|
/* UART TX ring buffer size. If set to zero, driver will not use TX buffer, TX function will
|
126
141
|
block task until all data have been sent out.*/
|
@@ -133,17 +148,29 @@ void IDFUARTComponent::setup() {
|
|
133
148
|
return;
|
134
149
|
}
|
135
150
|
|
136
|
-
|
137
|
-
|
151
|
+
err = uart_set_rx_full_threshold(this->uart_num_, this->rx_full_threshold_);
|
152
|
+
if (err != ESP_OK) {
|
153
|
+
ESP_LOGW(TAG, "uart_set_rx_full_threshold failed: %s", esp_err_to_name(err));
|
154
|
+
this->mark_failed();
|
155
|
+
return;
|
156
|
+
}
|
138
157
|
|
139
|
-
|
140
|
-
uart_config_t uart_config = this->get_config_();
|
141
|
-
esp_err_t err = uart_param_config(this->uart_num_, &uart_config);
|
158
|
+
err = uart_set_rx_timeout(this->uart_num_, this->rx_timeout_);
|
142
159
|
if (err != ESP_OK) {
|
143
|
-
ESP_LOGW(TAG, "
|
160
|
+
ESP_LOGW(TAG, "uart_set_rx_timeout failed: %s", esp_err_to_name(err));
|
161
|
+
this->mark_failed();
|
162
|
+
return;
|
163
|
+
}
|
164
|
+
|
165
|
+
auto mode = this->flow_control_pin_ != nullptr ? UART_MODE_RS485_HALF_DUPLEX : UART_MODE_UART;
|
166
|
+
err = uart_set_mode(this->uart_num_, mode);
|
167
|
+
if (err != ESP_OK) {
|
168
|
+
ESP_LOGW(TAG, "uart_set_mode failed: %s", esp_err_to_name(err));
|
144
169
|
this->mark_failed();
|
145
170
|
return;
|
146
|
-
}
|
171
|
+
}
|
172
|
+
|
173
|
+
if (dump_config) {
|
147
174
|
ESP_LOGCONFIG(TAG, "UART %u was reloaded.", this->uart_num_);
|
148
175
|
this->dump_config();
|
149
176
|
}
|
@@ -153,8 +180,13 @@ void IDFUARTComponent::dump_config() {
|
|
153
180
|
ESP_LOGCONFIG(TAG, "UART Bus %u:", this->uart_num_);
|
154
181
|
LOG_PIN(" TX Pin: ", tx_pin_);
|
155
182
|
LOG_PIN(" RX Pin: ", rx_pin_);
|
183
|
+
LOG_PIN(" Flow Control Pin: ", flow_control_pin_);
|
156
184
|
if (this->rx_pin_ != nullptr) {
|
157
|
-
ESP_LOGCONFIG(TAG,
|
185
|
+
ESP_LOGCONFIG(TAG,
|
186
|
+
" RX Buffer Size: %u\n"
|
187
|
+
" RX Full Threshold: %u\n"
|
188
|
+
" RX Timeout: %u",
|
189
|
+
this->rx_buffer_size_, this->rx_full_threshold_, this->rx_timeout_);
|
158
190
|
}
|
159
191
|
ESP_LOGCONFIG(TAG,
|
160
192
|
" Baud Rate: %" PRIu32 " baud\n"
|
@@ -165,6 +197,28 @@ void IDFUARTComponent::dump_config() {
|
|
165
197
|
this->check_logger_conflict();
|
166
198
|
}
|
167
199
|
|
200
|
+
void IDFUARTComponent::set_rx_full_threshold(size_t rx_full_threshold) {
|
201
|
+
if (this->is_ready()) {
|
202
|
+
esp_err_t err = uart_set_rx_full_threshold(this->uart_num_, rx_full_threshold);
|
203
|
+
if (err != ESP_OK) {
|
204
|
+
ESP_LOGW(TAG, "uart_set_rx_full_threshold failed: %s", esp_err_to_name(err));
|
205
|
+
return;
|
206
|
+
}
|
207
|
+
}
|
208
|
+
this->rx_full_threshold_ = rx_full_threshold;
|
209
|
+
}
|
210
|
+
|
211
|
+
void IDFUARTComponent::set_rx_timeout(size_t rx_timeout) {
|
212
|
+
if (this->is_ready()) {
|
213
|
+
esp_err_t err = uart_set_rx_timeout(this->uart_num_, rx_timeout);
|
214
|
+
if (err != ESP_OK) {
|
215
|
+
ESP_LOGW(TAG, "uart_set_rx_timeout failed: %s", esp_err_to_name(err));
|
216
|
+
return;
|
217
|
+
}
|
218
|
+
}
|
219
|
+
this->rx_timeout_ = rx_timeout;
|
220
|
+
}
|
221
|
+
|
168
222
|
void IDFUARTComponent::write_array(const uint8_t *data, size_t len) {
|
169
223
|
xSemaphoreTake(this->lock_, portMAX_DELAY);
|
170
224
|
uart_write_bytes(this->uart_num_, data, len);
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#pragma once
|
2
2
|
|
3
|
-
#ifdef
|
3
|
+
#ifdef USE_ESP32
|
4
4
|
|
5
5
|
#include <driver/uart.h>
|
6
6
|
#include "esphome/core/component.h"
|
@@ -15,6 +15,9 @@ class IDFUARTComponent : public UARTComponent, public Component {
|
|
15
15
|
void dump_config() override;
|
16
16
|
float get_setup_priority() const override { return setup_priority::BUS; }
|
17
17
|
|
18
|
+
void set_rx_full_threshold(size_t rx_full_threshold) override;
|
19
|
+
void set_rx_timeout(size_t rx_timeout) override;
|
20
|
+
|
18
21
|
void write_array(const uint8_t *data, size_t len) override;
|
19
22
|
|
20
23
|
bool peek_byte(uint8_t *data) override;
|
@@ -55,4 +58,4 @@ class IDFUARTComponent : public UARTComponent, public Component {
|
|
55
58
|
} // namespace uart
|
56
59
|
} // namespace esphome
|
57
60
|
|
58
|
-
#endif //
|
61
|
+
#endif // USE_ESP32
|
@@ -58,7 +58,7 @@ void UponorSmatrixClimate::control(const climate::ClimateCall &call) {
|
|
58
58
|
}
|
59
59
|
|
60
60
|
void UponorSmatrixClimate::on_device_data(const UponorSmatrixData *data, size_t data_len) {
|
61
|
-
for (
|
61
|
+
for (size_t i = 0; i < data_len; i++) {
|
62
62
|
switch (data[i].id) {
|
63
63
|
case UPONOR_ID_TARGET_TEMP_MIN:
|
64
64
|
this->min_temperature_ = raw_to_celsius(data[i].value);
|
@@ -18,7 +18,7 @@ void UponorSmatrixSensor::dump_config() {
|
|
18
18
|
}
|
19
19
|
|
20
20
|
void UponorSmatrixSensor::on_device_data(const UponorSmatrixData *data, size_t data_len) {
|
21
|
-
for (
|
21
|
+
for (size_t i = 0; i < data_len; i++) {
|
22
22
|
switch (data[i].id) {
|
23
23
|
case UPONOR_ID_ROOM_TEMP:
|
24
24
|
if (this->temperature_sensor_ != nullptr)
|