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
@@ -7,12 +7,25 @@
|
|
7
7
|
#include "esphome/core/helpers.h"
|
8
8
|
#include "esphome/core/log.h"
|
9
9
|
#include "esphome/core/preferences.h"
|
10
|
+
#include "esphome/core/hash_base.h"
|
10
11
|
|
11
12
|
namespace esphome {
|
12
13
|
|
13
14
|
/// ESPHomeOTAComponent provides a simple way to integrate Over-the-Air updates into your app using ArduinoOTA.
|
14
15
|
class ESPHomeOTAComponent : public ota::OTAComponent {
|
15
16
|
public:
|
17
|
+
enum class OTAState : uint8_t {
|
18
|
+
IDLE,
|
19
|
+
MAGIC_READ, // Reading magic bytes
|
20
|
+
MAGIC_ACK, // Sending OK and version after magic bytes
|
21
|
+
FEATURE_READ, // Reading feature flags from client
|
22
|
+
FEATURE_ACK, // Sending feature acknowledgment
|
23
|
+
#ifdef USE_OTA_PASSWORD
|
24
|
+
AUTH_SEND, // Sending authentication request
|
25
|
+
AUTH_READ, // Reading authentication data
|
26
|
+
#endif // USE_OTA_PASSWORD
|
27
|
+
DATA, // BLOCKING! Processing OTA data (update, etc.)
|
28
|
+
};
|
16
29
|
#ifdef USE_OTA_PASSWORD
|
17
30
|
void set_auth_password(const std::string &password) { password_ = password; }
|
18
31
|
#endif // USE_OTA_PASSWORD
|
@@ -30,12 +43,38 @@ class ESPHomeOTAComponent : public ota::OTAComponent {
|
|
30
43
|
protected:
|
31
44
|
void handle_handshake_();
|
32
45
|
void handle_data_();
|
46
|
+
#ifdef USE_OTA_PASSWORD
|
47
|
+
bool handle_auth_send_();
|
48
|
+
bool handle_auth_read_();
|
49
|
+
bool select_auth_type_();
|
50
|
+
size_t get_auth_hex_size_() const;
|
51
|
+
void cleanup_auth_();
|
52
|
+
void log_auth_warning_(const LogString *msg);
|
53
|
+
#endif // USE_OTA_PASSWORD
|
33
54
|
bool readall_(uint8_t *buf, size_t len);
|
34
55
|
bool writeall_(const uint8_t *buf, size_t len);
|
56
|
+
|
57
|
+
bool try_read_(size_t to_read, const LogString *desc);
|
58
|
+
bool try_write_(size_t to_write, const LogString *desc);
|
59
|
+
|
60
|
+
inline bool would_block_(int error_code) const { return error_code == EAGAIN || error_code == EWOULDBLOCK; }
|
61
|
+
bool handle_read_error_(ssize_t read, const LogString *desc);
|
62
|
+
bool handle_write_error_(ssize_t written, const LogString *desc);
|
63
|
+
inline void transition_ota_state_(OTAState next_state) {
|
64
|
+
this->ota_state_ = next_state;
|
65
|
+
this->handshake_buf_pos_ = 0; // Reset buffer position for next state
|
66
|
+
}
|
67
|
+
|
35
68
|
void log_socket_error_(const LogString *msg);
|
36
69
|
void log_read_error_(const LogString *what);
|
37
70
|
void log_start_(const LogString *phase);
|
71
|
+
void log_remote_closed_(const LogString *during);
|
38
72
|
void cleanup_connection_();
|
73
|
+
inline void send_error_and_cleanup_(ota::OTAResponseTypes error) {
|
74
|
+
uint8_t error_byte = static_cast<uint8_t>(error);
|
75
|
+
this->client_->write(&error_byte, 1); // Best effort, non-blocking
|
76
|
+
this->cleanup_connection_();
|
77
|
+
}
|
39
78
|
void yield_and_feed_watchdog_();
|
40
79
|
|
41
80
|
#ifdef USE_OTA_PASSWORD
|
@@ -44,11 +83,19 @@ class ESPHomeOTAComponent : public ota::OTAComponent {
|
|
44
83
|
|
45
84
|
std::unique_ptr<socket::Socket> server_;
|
46
85
|
std::unique_ptr<socket::Socket> client_;
|
86
|
+
std::unique_ptr<ota::OTABackend> backend_;
|
47
87
|
|
48
88
|
uint32_t client_connect_time_{0};
|
49
89
|
uint16_t port_;
|
50
|
-
uint8_t
|
51
|
-
|
90
|
+
uint8_t handshake_buf_[5];
|
91
|
+
OTAState ota_state_{OTAState::IDLE};
|
92
|
+
uint8_t handshake_buf_pos_{0};
|
93
|
+
uint8_t ota_features_{0};
|
94
|
+
#ifdef USE_OTA_PASSWORD
|
95
|
+
std::unique_ptr<uint8_t[]> auth_buf_;
|
96
|
+
uint8_t auth_buf_pos_{0};
|
97
|
+
uint8_t auth_type_{0}; // Store auth type to know which hasher to use
|
98
|
+
#endif // USE_OTA_PASSWORD
|
52
99
|
};
|
53
100
|
|
54
101
|
} // namespace esphome
|
@@ -2,9 +2,15 @@ import logging
|
|
2
2
|
|
3
3
|
from esphome import pins
|
4
4
|
import esphome.codegen as cg
|
5
|
-
from esphome.components.esp32 import
|
5
|
+
from esphome.components.esp32 import (
|
6
|
+
add_idf_component,
|
7
|
+
add_idf_sdkconfig_option,
|
8
|
+
get_esp32_variant,
|
9
|
+
)
|
6
10
|
from esphome.components.esp32.const import (
|
11
|
+
VARIANT_ESP32,
|
7
12
|
VARIANT_ESP32C3,
|
13
|
+
VARIANT_ESP32P4,
|
8
14
|
VARIANT_ESP32S2,
|
9
15
|
VARIANT_ESP32S3,
|
10
16
|
)
|
@@ -21,6 +27,7 @@ from esphome.const import (
|
|
21
27
|
CONF_GATEWAY,
|
22
28
|
CONF_ID,
|
23
29
|
CONF_INTERRUPT_PIN,
|
30
|
+
CONF_MAC_ADDRESS,
|
24
31
|
CONF_MANUAL_IP,
|
25
32
|
CONF_MISO_PIN,
|
26
33
|
CONF_MODE,
|
@@ -75,12 +82,14 @@ ETHERNET_TYPES = {
|
|
75
82
|
"W5500": EthernetType.ETHERNET_TYPE_W5500,
|
76
83
|
"OPENETH": EthernetType.ETHERNET_TYPE_OPENETH,
|
77
84
|
"DM9051": EthernetType.ETHERNET_TYPE_DM9051,
|
85
|
+
"LAN8670": EthernetType.ETHERNET_TYPE_LAN8670,
|
78
86
|
}
|
79
87
|
|
80
88
|
# PHY types that need compile-time defines for conditional compilation
|
81
89
|
_PHY_TYPE_TO_DEFINE = {
|
82
90
|
"KSZ8081": "USE_ETHERNET_KSZ8081",
|
83
91
|
"KSZ8081RNA": "USE_ETHERNET_KSZ8081",
|
92
|
+
"LAN8670": "USE_ETHERNET_LAN8670",
|
84
93
|
# Add other PHY types here only if they need conditional compilation
|
85
94
|
}
|
86
95
|
|
@@ -117,19 +126,15 @@ ManualIP = ethernet_ns.struct("ManualIP")
|
|
117
126
|
|
118
127
|
def _is_framework_spi_polling_mode_supported():
|
119
128
|
# SPI Ethernet without IRQ feature is added in
|
120
|
-
# esp-idf >= (5.3+ ,5.2.1+, 5.1.4)
|
129
|
+
# esp-idf >= (5.3+ ,5.2.1+, 5.1.4)
|
130
|
+
# Note: Arduino now uses ESP-IDF as a component, so we only check IDF version
|
121
131
|
framework_version = CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION]
|
122
|
-
if
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
return True
|
129
|
-
return False
|
130
|
-
if CORE.using_arduino:
|
131
|
-
return framework_version >= cv.Version(3, 0, 0)
|
132
|
-
# fail safe: Unknown framework
|
132
|
+
if framework_version >= cv.Version(5, 3, 0):
|
133
|
+
return True
|
134
|
+
if cv.Version(5, 3, 0) > framework_version >= cv.Version(5, 2, 1):
|
135
|
+
return True
|
136
|
+
if cv.Version(5, 2, 0) > framework_version >= cv.Version(5, 1, 4): # noqa: SIM103
|
137
|
+
return True
|
133
138
|
return False
|
134
139
|
|
135
140
|
|
@@ -140,6 +145,7 @@ def _validate(config):
|
|
140
145
|
else:
|
141
146
|
use_address = CORE.name + config[CONF_DOMAIN]
|
142
147
|
config[CONF_USE_ADDRESS] = use_address
|
148
|
+
|
143
149
|
if config[CONF_TYPE] in SPI_ETHERNET_TYPES:
|
144
150
|
if _is_framework_spi_polling_mode_supported():
|
145
151
|
if CONF_POLLING_INTERVAL in config and CONF_INTERRUPT_PIN in config:
|
@@ -172,6 +178,12 @@ def _validate(config):
|
|
172
178
|
del config[CONF_CLK_MODE]
|
173
179
|
elif CONF_CLK not in config:
|
174
180
|
raise cv.Invalid("'clk' is a required option for [ethernet].")
|
181
|
+
variant = get_esp32_variant()
|
182
|
+
if variant not in (VARIANT_ESP32, VARIANT_ESP32P4):
|
183
|
+
raise cv.Invalid(
|
184
|
+
f"{config[CONF_TYPE]} PHY requires RMII interface and is only supported "
|
185
|
+
f"on ESP32 classic and ESP32-P4, not {variant}"
|
186
|
+
)
|
175
187
|
|
176
188
|
return config
|
177
189
|
|
@@ -186,6 +198,7 @@ BASE_SCHEMA = cv.Schema(
|
|
186
198
|
"This option has been removed. Please use the [disabled] option under the "
|
187
199
|
"new mdns component instead."
|
188
200
|
),
|
201
|
+
cv.Optional(CONF_MAC_ADDRESS): cv.mac_address,
|
189
202
|
}
|
190
203
|
).extend(cv.COMPONENT_SCHEMA)
|
191
204
|
|
@@ -252,6 +265,7 @@ CONFIG_SCHEMA = cv.All(
|
|
252
265
|
"W5500": SPI_SCHEMA,
|
253
266
|
"OPENETH": BASE_SCHEMA,
|
254
267
|
"DM9051": SPI_SCHEMA,
|
268
|
+
"LAN8670": RMII_SCHEMA,
|
255
269
|
},
|
256
270
|
upper=True,
|
257
271
|
),
|
@@ -322,11 +336,8 @@ async def to_code(config):
|
|
322
336
|
cg.add(var.set_clock_speed(config[CONF_CLOCK_SPEED]))
|
323
337
|
|
324
338
|
cg.add_define("USE_ETHERNET_SPI")
|
325
|
-
|
326
|
-
|
327
|
-
add_idf_sdkconfig_option(
|
328
|
-
f"CONFIG_ETH_SPI_ETHERNET_{config[CONF_TYPE]}", True
|
329
|
-
)
|
339
|
+
add_idf_sdkconfig_option("CONFIG_ETH_USE_SPI_ETHERNET", True)
|
340
|
+
add_idf_sdkconfig_option(f"CONFIG_ETH_SPI_ETHERNET_{config[CONF_TYPE]}", True)
|
330
341
|
elif config[CONF_TYPE] == "OPENETH":
|
331
342
|
cg.add_define("USE_ETHERNET_OPENETH")
|
332
343
|
add_idf_sdkconfig_option("CONFIG_ETH_USE_OPENETH", True)
|
@@ -356,13 +367,19 @@ async def to_code(config):
|
|
356
367
|
if phy_define := _PHY_TYPE_TO_DEFINE.get(config[CONF_TYPE]):
|
357
368
|
cg.add_define(phy_define)
|
358
369
|
|
370
|
+
if mac_address := config.get(CONF_MAC_ADDRESS):
|
371
|
+
cg.add(var.set_fixed_mac(mac_address.parts))
|
372
|
+
|
359
373
|
cg.add_define("USE_ETHERNET")
|
360
374
|
|
361
375
|
# Disable WiFi when using Ethernet to save memory
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
376
|
+
add_idf_sdkconfig_option("CONFIG_ESP_WIFI_ENABLED", False)
|
377
|
+
# Also disable WiFi/BT coexistence since WiFi is disabled
|
378
|
+
add_idf_sdkconfig_option("CONFIG_SW_COEXIST_ENABLE", False)
|
379
|
+
|
380
|
+
if config[CONF_TYPE] == "LAN8670":
|
381
|
+
# Add LAN867x 10BASE-T1S PHY support component
|
382
|
+
add_idf_component(name="espressif/lan867x", ref="2.0.0")
|
366
383
|
|
367
384
|
if CORE.using_arduino:
|
368
385
|
cg.add_library("WiFi", None)
|
@@ -9,6 +9,10 @@
|
|
9
9
|
#include <cinttypes>
|
10
10
|
#include "esp_event.h"
|
11
11
|
|
12
|
+
#ifdef USE_ETHERNET_LAN8670
|
13
|
+
#include "esp_eth_phy_lan867x.h"
|
14
|
+
#endif
|
15
|
+
|
12
16
|
#ifdef USE_ETHERNET_SPI
|
13
17
|
#include <driver/gpio.h>
|
14
18
|
#include <driver/spi_master.h>
|
@@ -37,17 +41,20 @@ static const char *const TAG = "ethernet";
|
|
37
41
|
|
38
42
|
EthernetComponent *global_eth_component; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
39
43
|
|
44
|
+
void EthernetComponent::log_error_and_mark_failed_(esp_err_t err, const char *message) {
|
45
|
+
ESP_LOGE(TAG, "%s: (%d) %s", message, err, esp_err_to_name(err));
|
46
|
+
this->mark_failed();
|
47
|
+
}
|
48
|
+
|
40
49
|
#define ESPHL_ERROR_CHECK(err, message) \
|
41
50
|
if ((err) != ESP_OK) { \
|
42
|
-
|
43
|
-
this->mark_failed(); \
|
51
|
+
this->log_error_and_mark_failed_(err, message); \
|
44
52
|
return; \
|
45
53
|
}
|
46
54
|
|
47
55
|
#define ESPHL_ERROR_CHECK_RET(err, message, ret) \
|
48
56
|
if ((err) != ESP_OK) { \
|
49
|
-
|
50
|
-
this->mark_failed(); \
|
57
|
+
this->log_error_and_mark_failed_(err, message); \
|
51
58
|
return ret; \
|
52
59
|
}
|
53
60
|
|
@@ -200,6 +207,12 @@ void EthernetComponent::setup() {
|
|
200
207
|
this->phy_ = esp_eth_phy_new_ksz80xx(&phy_config);
|
201
208
|
break;
|
202
209
|
}
|
210
|
+
#ifdef USE_ETHERNET_LAN8670
|
211
|
+
case ETHERNET_TYPE_LAN8670: {
|
212
|
+
this->phy_ = esp_eth_phy_new_lan867x(&phy_config);
|
213
|
+
break;
|
214
|
+
}
|
215
|
+
#endif
|
203
216
|
#endif
|
204
217
|
#ifdef USE_ETHERNET_SPI
|
205
218
|
#if CONFIG_ETH_SPI_ETHERNET_W5500
|
@@ -243,7 +256,11 @@ void EthernetComponent::setup() {
|
|
243
256
|
|
244
257
|
// use ESP internal eth mac
|
245
258
|
uint8_t mac_addr[6];
|
246
|
-
|
259
|
+
if (this->fixed_mac_.has_value()) {
|
260
|
+
memcpy(mac_addr, this->fixed_mac_->data(), 6);
|
261
|
+
} else {
|
262
|
+
esp_read_mac(mac_addr, ESP_MAC_ETH);
|
263
|
+
}
|
247
264
|
err = esp_eth_ioctl(this->eth_handle_, ETH_CMD_S_MAC_ADDR, mac_addr);
|
248
265
|
ESPHL_ERROR_CHECK(err, "set mac address error");
|
249
266
|
|
@@ -353,6 +370,12 @@ void EthernetComponent::dump_config() {
|
|
353
370
|
eth_type = "DM9051";
|
354
371
|
break;
|
355
372
|
|
373
|
+
#ifdef USE_ETHERNET_LAN8670
|
374
|
+
case ETHERNET_TYPE_LAN8670:
|
375
|
+
eth_type = "LAN8670";
|
376
|
+
break;
|
377
|
+
#endif
|
378
|
+
|
356
379
|
default:
|
357
380
|
eth_type = "Unknown";
|
358
381
|
break;
|
@@ -28,6 +28,7 @@ enum EthernetType : uint8_t {
|
|
28
28
|
ETHERNET_TYPE_W5500,
|
29
29
|
ETHERNET_TYPE_OPENETH,
|
30
30
|
ETHERNET_TYPE_DM9051,
|
31
|
+
ETHERNET_TYPE_LAN8670,
|
31
32
|
};
|
32
33
|
|
33
34
|
struct ManualIP {
|
@@ -83,6 +84,7 @@ class EthernetComponent : public Component {
|
|
83
84
|
#endif
|
84
85
|
void set_type(EthernetType type);
|
85
86
|
void set_manual_ip(const ManualIP &manual_ip);
|
87
|
+
void set_fixed_mac(const std::array<uint8_t, 6> &mac) { this->fixed_mac_ = mac; }
|
86
88
|
|
87
89
|
network::IPAddresses get_ip_addresses();
|
88
90
|
network::IPAddress get_dns_address(uint8_t num);
|
@@ -104,6 +106,7 @@ class EthernetComponent : public Component {
|
|
104
106
|
void start_connect_();
|
105
107
|
void finish_connect_();
|
106
108
|
void dump_connect_params_();
|
109
|
+
void log_error_and_mark_failed_(esp_err_t err, const char *message);
|
107
110
|
#ifdef USE_ETHERNET_KSZ8081
|
108
111
|
/// @brief Set `RMII Reference Clock Select` bit for KSZ8081.
|
109
112
|
void ksz8081_set_clock_reference_(esp_eth_mac_t *mac);
|
@@ -154,12 +157,13 @@ class EthernetComponent : public Component {
|
|
154
157
|
esp_netif_t *eth_netif_{nullptr};
|
155
158
|
esp_eth_handle_t eth_handle_;
|
156
159
|
esp_eth_phy_t *phy_{nullptr};
|
160
|
+
optional<std::array<uint8_t, 6>> fixed_mac_;
|
157
161
|
};
|
158
162
|
|
159
163
|
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
|
160
164
|
extern EthernetComponent *global_eth_component;
|
161
165
|
|
162
|
-
#if
|
166
|
+
#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 4, 2)
|
163
167
|
extern "C" esp_eth_phy_t *esp_eth_phy_new_jl1101(const eth_phy_config_t *config);
|
164
168
|
#endif
|
165
169
|
|
@@ -39,11 +39,13 @@ async def to_code(config):
|
|
39
39
|
pass
|
40
40
|
|
41
41
|
|
42
|
-
def _process_git_config(config: dict, refresh) -> str:
|
42
|
+
def _process_git_config(config: dict, refresh, skip_update: bool = False) -> str:
|
43
|
+
# When skip_update is True, use NEVER_REFRESH to prevent updates
|
44
|
+
actual_refresh = git.NEVER_REFRESH if skip_update else refresh
|
43
45
|
repo_dir, _ = git.clone_or_update(
|
44
46
|
url=config[CONF_URL],
|
45
47
|
ref=config.get(CONF_REF),
|
46
|
-
refresh=
|
48
|
+
refresh=actual_refresh,
|
47
49
|
domain=DOMAIN,
|
48
50
|
username=config.get(CONF_USERNAME),
|
49
51
|
password=config.get(CONF_PASSWORD),
|
@@ -70,12 +72,12 @@ def _process_git_config(config: dict, refresh) -> str:
|
|
70
72
|
return components_dir
|
71
73
|
|
72
74
|
|
73
|
-
def _process_single_config(config: dict):
|
75
|
+
def _process_single_config(config: dict, skip_update: bool = False):
|
74
76
|
conf = config[CONF_SOURCE]
|
75
77
|
if conf[CONF_TYPE] == TYPE_GIT:
|
76
78
|
with cv.prepend_path([CONF_SOURCE]):
|
77
79
|
components_dir = _process_git_config(
|
78
|
-
config[CONF_SOURCE], config[CONF_REFRESH]
|
80
|
+
config[CONF_SOURCE], config[CONF_REFRESH], skip_update
|
79
81
|
)
|
80
82
|
elif conf[CONF_TYPE] == TYPE_LOCAL:
|
81
83
|
components_dir = Path(CORE.relative_config_path(conf[CONF_PATH]))
|
@@ -105,7 +107,7 @@ def _process_single_config(config: dict):
|
|
105
107
|
loader.install_meta_finder(components_dir, allowed_components=allowed_components)
|
106
108
|
|
107
109
|
|
108
|
-
def do_external_components_pass(config: dict) -> None:
|
110
|
+
def do_external_components_pass(config: dict, skip_update: bool = False) -> None:
|
109
111
|
conf = config.get(DOMAIN)
|
110
112
|
if conf is None:
|
111
113
|
return
|
@@ -113,4 +115,4 @@ def do_external_components_pass(config: dict) -> None:
|
|
113
115
|
conf = CONFIG_SCHEMA(conf)
|
114
116
|
for i, c in enumerate(conf):
|
115
117
|
with cv.prepend_path(i):
|
116
|
-
_process_single_config(c)
|
118
|
+
_process_single_config(c, skip_update)
|
@@ -80,7 +80,7 @@ void FingerprintGrowComponent::setup() {
|
|
80
80
|
delay(20); // This delay guarantees the sensor will in fact be powered power.
|
81
81
|
|
82
82
|
if (this->check_password_()) {
|
83
|
-
if (this->new_password_ !=
|
83
|
+
if (this->new_password_ != std::numeric_limits<uint32_t>::max()) {
|
84
84
|
if (this->set_password_())
|
85
85
|
return;
|
86
86
|
} else {
|
@@ -6,6 +6,7 @@
|
|
6
6
|
#include "esphome/components/binary_sensor/binary_sensor.h"
|
7
7
|
#include "esphome/components/uart/uart.h"
|
8
8
|
|
9
|
+
#include <limits>
|
9
10
|
#include <vector>
|
10
11
|
|
11
12
|
namespace esphome {
|
@@ -177,7 +178,7 @@ class FingerprintGrowComponent : public PollingComponent, public uart::UARTDevic
|
|
177
178
|
uint8_t address_[4] = {0xFF, 0xFF, 0xFF, 0xFF};
|
178
179
|
uint16_t capacity_ = 64;
|
179
180
|
uint32_t password_ = 0x0;
|
180
|
-
uint32_t new_password_ =
|
181
|
+
uint32_t new_password_ = std::numeric_limits<uint32_t>::max();
|
181
182
|
GPIOPin *sensing_pin_{nullptr};
|
182
183
|
GPIOPin *sensor_power_pin_{nullptr};
|
183
184
|
uint8_t enrollment_image_ = 0;
|
@@ -3,7 +3,6 @@ import functools
|
|
3
3
|
import hashlib
|
4
4
|
from itertools import accumulate
|
5
5
|
import logging
|
6
|
-
import os
|
7
6
|
from pathlib import Path
|
8
7
|
import re
|
9
8
|
|
@@ -38,6 +37,7 @@ from esphome.const import (
|
|
38
37
|
)
|
39
38
|
from esphome.core import CORE, HexInt
|
40
39
|
from esphome.helpers import cpp_string_escape
|
40
|
+
from esphome.types import ConfigType
|
41
41
|
|
42
42
|
_LOGGER = logging.getLogger(__name__)
|
43
43
|
|
@@ -253,11 +253,11 @@ def validate_truetype_file(value):
|
|
253
253
|
return CORE.relative_config_path(cv.file_(value))
|
254
254
|
|
255
255
|
|
256
|
-
def add_local_file(value):
|
256
|
+
def add_local_file(value: ConfigType) -> ConfigType:
|
257
257
|
if value in FONT_CACHE:
|
258
258
|
return value
|
259
|
-
path = value[CONF_PATH]
|
260
|
-
if not
|
259
|
+
path = Path(value[CONF_PATH])
|
260
|
+
if not path.is_file():
|
261
261
|
raise cv.Invalid(f"File '{path}' not found.")
|
262
262
|
FONT_CACHE[value] = path
|
263
263
|
return value
|
@@ -318,7 +318,7 @@ def download_gfont(value):
|
|
318
318
|
external_files.compute_local_file_dir(DOMAIN)
|
319
319
|
/ f"{value[CONF_FAMILY]}@{value[CONF_WEIGHT]}@{value[CONF_ITALIC]}@v1.ttf"
|
320
320
|
)
|
321
|
-
if not external_files.is_file_recent(
|
321
|
+
if not external_files.is_file_recent(path, value[CONF_REFRESH]):
|
322
322
|
_LOGGER.debug("download_gfont: path=%s", path)
|
323
323
|
try:
|
324
324
|
req = requests.get(url, timeout=external_files.NETWORK_TIMEOUT)
|
@@ -179,7 +179,7 @@ void Graph::draw(Display *buff, uint16_t x_offset, uint16_t y_offset, Color colo
|
|
179
179
|
if (b) {
|
180
180
|
int16_t y = (int16_t) roundf((this->height_ - 1) * (1.0 - v)) - thick / 2 + y_offset;
|
181
181
|
auto draw_pixel_at = [&buff, c, y_offset, this](int16_t x, int16_t y) {
|
182
|
-
if (y >= y_offset && y < y_offset + this->height_)
|
182
|
+
if (y >= y_offset && static_cast<uint32_t>(y) < y_offset + this->height_)
|
183
183
|
buff->draw_pixel_at(x, y, c);
|
184
184
|
};
|
185
185
|
if (!continuous || !has_prev || !prev_b || (abs(y - prev_y) <= thick)) {
|
@@ -116,7 +116,7 @@ void GraphicalDisplayMenu::draw_menu_internal_(display::Display *display, const
|
|
116
116
|
int number_items_fit_to_screen = 0;
|
117
117
|
const int max_item_index = this->displayed_item_->items_size() - 1;
|
118
118
|
|
119
|
-
for (size_t i = 0; i <= max_item_index; i++) {
|
119
|
+
for (size_t i = 0; max_item_index >= 0 && i <= static_cast<size_t>(max_item_index); i++) {
|
120
120
|
const auto *item = this->displayed_item_->get_item(i);
|
121
121
|
const bool selected = i == this->cursor_index_;
|
122
122
|
const display::Rect item_dimensions = this->measure_item(display, item, bounds, selected);
|
@@ -174,7 +174,8 @@ void GraphicalDisplayMenu::draw_menu_internal_(display::Display *display, const
|
|
174
174
|
|
175
175
|
display->filled_rectangle(bounds->x, bounds->y, max_width, total_height, this->background_color_);
|
176
176
|
auto y_offset = bounds->y;
|
177
|
-
for (size_t i = first_item_index;
|
177
|
+
for (size_t i = static_cast<size_t>(first_item_index);
|
178
|
+
last_item_index >= 0 && i <= static_cast<size_t>(last_item_index); i++) {
|
178
179
|
const auto *item = this->displayed_item_->get_item(i);
|
179
180
|
const bool selected = i == this->cursor_index_;
|
180
181
|
display::Rect dimensions = menu_dimensions[i];
|
@@ -213,7 +213,7 @@ haier_protocol::HandlerError HonClimate::status_handler_(haier_protocol::FrameTy
|
|
213
213
|
this->real_control_packet_size_);
|
214
214
|
this->status_message_callback_.call((const char *) data, data_size);
|
215
215
|
} else {
|
216
|
-
ESP_LOGW(TAG, "Status packet too small: %
|
216
|
+
ESP_LOGW(TAG, "Status packet too small: %zu (should be >= %zu)", data_size, this->real_control_packet_size_);
|
217
217
|
}
|
218
218
|
switch (this->protocol_phase_) {
|
219
219
|
case ProtocolPhases::SENDING_FIRST_STATUS_REQUEST:
|
@@ -827,7 +827,7 @@ haier_protocol::HandlerError HonClimate::process_status_message_(const uint8_t *
|
|
827
827
|
size_t expected_size =
|
828
828
|
2 + this->status_message_header_size_ + this->real_control_packet_size_ + this->real_sensors_packet_size_;
|
829
829
|
if (size < expected_size) {
|
830
|
-
ESP_LOGW(TAG, "Unexpected message size %
|
830
|
+
ESP_LOGW(TAG, "Unexpected message size %u (expexted >= %zu)", size, expected_size);
|
831
831
|
return haier_protocol::HandlerError::WRONG_MESSAGE_STRUCTURE;
|
832
832
|
}
|
833
833
|
uint16_t subtype = (((uint16_t) packet_buffer[0]) << 8) + packet_buffer[1];
|
@@ -178,7 +178,7 @@ class HonClimate : public HaierClimateBase {
|
|
178
178
|
int extra_control_packet_bytes_{0};
|
179
179
|
int extra_sensors_packet_bytes_{4};
|
180
180
|
int status_message_header_size_{0};
|
181
|
-
|
181
|
+
size_t real_control_packet_size_{sizeof(hon_protocol::HaierPacketControl)};
|
182
182
|
int real_sensors_packet_size_{sizeof(hon_protocol::HaierPacketSensors) + 4};
|
183
183
|
HonControlMethod control_method_;
|
184
184
|
std::queue<haier_protocol::HaierMessage> control_messages_queue_;
|
@@ -7,24 +7,20 @@ namespace hdc1080 {
|
|
7
7
|
|
8
8
|
static const char *const TAG = "hdc1080";
|
9
9
|
|
10
|
-
static const uint8_t HDC1080_ADDRESS = 0x40; // 0b1000000 from datasheet
|
11
10
|
static const uint8_t HDC1080_CMD_CONFIGURATION = 0x02;
|
12
11
|
static const uint8_t HDC1080_CMD_TEMPERATURE = 0x00;
|
13
12
|
static const uint8_t HDC1080_CMD_HUMIDITY = 0x01;
|
14
13
|
|
15
14
|
void HDC1080Component::setup() {
|
16
|
-
const uint8_t
|
17
|
-
0b00000000, // resolution 14bit for both humidity and temperature
|
18
|
-
0b00000000 // reserved
|
19
|
-
};
|
15
|
+
const uint8_t config[2] = {0x00, 0x00}; // resolution 14bit for both humidity and temperature
|
20
16
|
|
21
|
-
if
|
22
|
-
|
23
|
-
|
24
|
-
this->status_set_warning();
|
17
|
+
// if configuration fails - there is a problem
|
18
|
+
if (this->write_register(HDC1080_CMD_CONFIGURATION, config, 2) != i2c::ERROR_OK) {
|
19
|
+
this->mark_failed();
|
25
20
|
return;
|
26
21
|
}
|
27
22
|
}
|
23
|
+
|
28
24
|
void HDC1080Component::dump_config() {
|
29
25
|
ESP_LOGCONFIG(TAG, "HDC1080:");
|
30
26
|
LOG_I2C_DEVICE(this);
|
@@ -35,39 +31,51 @@ void HDC1080Component::dump_config() {
|
|
35
31
|
LOG_SENSOR(" ", "Temperature", this->temperature_);
|
36
32
|
LOG_SENSOR(" ", "Humidity", this->humidity_);
|
37
33
|
}
|
34
|
+
|
38
35
|
void HDC1080Component::update() {
|
39
|
-
|
36
|
+
// regardless of what sensor/s are defined in yaml configuration
|
37
|
+
// the hdc1080 setup configuration used, requires both temperature and humidity to be read
|
38
|
+
|
39
|
+
this->status_clear_warning();
|
40
|
+
|
40
41
|
if (this->write(&HDC1080_CMD_TEMPERATURE, 1) != i2c::ERROR_OK) {
|
41
42
|
this->status_set_warning();
|
42
43
|
return;
|
43
44
|
}
|
44
|
-
delay(20);
|
45
|
-
if (this->read(reinterpret_cast<uint8_t *>(&raw_temp), 2) != i2c::ERROR_OK) {
|
46
|
-
this->status_set_warning();
|
47
|
-
return;
|
48
|
-
}
|
49
|
-
raw_temp = i2c::i2ctohs(raw_temp);
|
50
|
-
float temp = raw_temp * 0.0025177f - 40.0f; // raw * 2^-16 * 165 - 40
|
51
|
-
this->temperature_->publish_state(temp);
|
52
45
|
|
53
|
-
|
54
|
-
|
55
|
-
this->
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
if (this->read(reinterpret_cast<uint8_t *>(&raw_humidity), 2) != i2c::ERROR_OK) {
|
60
|
-
this->status_set_warning();
|
61
|
-
return;
|
62
|
-
}
|
63
|
-
raw_humidity = i2c::i2ctohs(raw_humidity);
|
64
|
-
float humidity = raw_humidity * 0.001525879f; // raw * 2^-16 * 100
|
65
|
-
this->humidity_->publish_state(humidity);
|
46
|
+
this->set_timeout(20, [this]() {
|
47
|
+
uint16_t raw_temperature;
|
48
|
+
if (this->read(reinterpret_cast<uint8_t *>(&raw_temperature), 2) != i2c::ERROR_OK) {
|
49
|
+
this->status_set_warning();
|
50
|
+
return;
|
51
|
+
}
|
66
52
|
|
67
|
-
|
68
|
-
|
53
|
+
if (this->temperature_ != nullptr) {
|
54
|
+
raw_temperature = i2c::i2ctohs(raw_temperature);
|
55
|
+
float temperature = raw_temperature * 0.0025177f - 40.0f; // raw * 2^-16 * 165 - 40
|
56
|
+
this->temperature_->publish_state(temperature);
|
57
|
+
}
|
58
|
+
|
59
|
+
if (this->write(&HDC1080_CMD_HUMIDITY, 1) != i2c::ERROR_OK) {
|
60
|
+
this->status_set_warning();
|
61
|
+
return;
|
62
|
+
}
|
63
|
+
|
64
|
+
this->set_timeout(20, [this]() {
|
65
|
+
uint16_t raw_humidity;
|
66
|
+
if (this->read(reinterpret_cast<uint8_t *>(&raw_humidity), 2) != i2c::ERROR_OK) {
|
67
|
+
this->status_set_warning();
|
68
|
+
return;
|
69
|
+
}
|
70
|
+
|
71
|
+
if (this->humidity_ != nullptr) {
|
72
|
+
raw_humidity = i2c::i2ctohs(raw_humidity);
|
73
|
+
float humidity = raw_humidity * 0.001525879f; // raw * 2^-16 * 100
|
74
|
+
this->humidity_->publish_state(humidity);
|
75
|
+
}
|
76
|
+
});
|
77
|
+
});
|
69
78
|
}
|
70
|
-
float HDC1080Component::get_setup_priority() const { return setup_priority::DATA; }
|
71
79
|
|
72
80
|
} // namespace hdc1080
|
73
81
|
} // namespace esphome
|
@@ -12,13 +12,11 @@ class HDC1080Component : public PollingComponent, public i2c::I2CDevice {
|
|
12
12
|
void set_temperature(sensor::Sensor *temperature) { temperature_ = temperature; }
|
13
13
|
void set_humidity(sensor::Sensor *humidity) { humidity_ = humidity; }
|
14
14
|
|
15
|
-
/// Setup the sensor and check for connection.
|
16
15
|
void setup() override;
|
17
16
|
void dump_config() override;
|
18
|
-
/// Retrieve the latest sensor values. This operation takes approximately 16ms.
|
19
17
|
void update() override;
|
20
18
|
|
21
|
-
float get_setup_priority() const override;
|
19
|
+
float get_setup_priority() const override { return setup_priority::DATA; }
|
22
20
|
|
23
21
|
protected:
|
24
22
|
sensor::Sensor *temperature_{nullptr};
|
@@ -87,7 +87,7 @@ void HomeassistantNumber::control(float value) {
|
|
87
87
|
static constexpr auto ENTITY_ID_KEY = StringRef::from_lit("entity_id");
|
88
88
|
static constexpr auto VALUE_KEY = StringRef::from_lit("value");
|
89
89
|
|
90
|
-
api::
|
90
|
+
api::HomeassistantActionRequest resp;
|
91
91
|
resp.set_service(SERVICE_NAME);
|
92
92
|
|
93
93
|
resp.data.emplace_back();
|
@@ -100,7 +100,7 @@ void HomeassistantNumber::control(float value) {
|
|
100
100
|
entity_value.set_key(VALUE_KEY);
|
101
101
|
entity_value.value = to_string(value);
|
102
102
|
|
103
|
-
api::global_api_server->
|
103
|
+
api::global_api_server->send_homeassistant_action(resp);
|
104
104
|
}
|
105
105
|
|
106
106
|
} // namespace homeassistant
|
@@ -44,7 +44,7 @@ void HomeassistantSwitch::write_state(bool state) {
|
|
44
44
|
static constexpr auto SERVICE_OFF = StringRef::from_lit("homeassistant.turn_off");
|
45
45
|
static constexpr auto ENTITY_ID_KEY = StringRef::from_lit("entity_id");
|
46
46
|
|
47
|
-
api::
|
47
|
+
api::HomeassistantActionRequest resp;
|
48
48
|
if (state) {
|
49
49
|
resp.set_service(SERVICE_ON);
|
50
50
|
} else {
|
@@ -56,7 +56,7 @@ void HomeassistantSwitch::write_state(bool state) {
|
|
56
56
|
entity_id_kv.set_key(ENTITY_ID_KEY);
|
57
57
|
entity_id_kv.value = this->entity_id_;
|
58
58
|
|
59
|
-
api::global_api_server->
|
59
|
+
api::global_api_server->send_homeassistant_action(resp);
|
60
60
|
}
|
61
61
|
|
62
62
|
} // namespace homeassistant
|