esphome 2025.5.2__py3-none-any.whl → 2025.6.0b1__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 +20 -14
- esphome/components/a4988/a4988.cpp +1 -1
- esphome/components/absolute_humidity/absolute_humidity.cpp +6 -4
- esphome/components/ac_dimmer/ac_dimmer.cpp +4 -2
- esphome/components/adc/adc_sensor_esp32.cpp +5 -3
- esphome/components/adc/adc_sensor_esp8266.cpp +5 -3
- esphome/components/adc/adc_sensor_libretiny.cpp +5 -3
- esphome/components/adc/adc_sensor_rp2040.cpp +5 -3
- esphome/components/adc128s102/adc128s102.cpp +1 -1
- esphome/components/ade7880/ade7880.cpp +28 -17
- esphome/components/ade7953_base/ade7953_base.cpp +12 -9
- esphome/components/ade7953_i2c/ade7953_i2c.cpp +1 -1
- esphome/components/ade7953_spi/ade7953_spi.cpp +1 -1
- esphome/components/ads1115/ads1115.cpp +3 -5
- esphome/components/ads1118/ads1118.cpp +2 -1
- esphome/components/ags10/ags10.cpp +3 -2
- esphome/components/aht10/aht10.cpp +27 -29
- esphome/components/aic3204/aic3204.cpp +2 -2
- esphome/components/alarm_control_panel/__init__.py +1 -0
- esphome/components/am2315c/am2315c.cpp +2 -2
- esphome/components/am2320/am2320.cpp +2 -2
- esphome/components/am43/am43_base.h +1 -1
- esphome/components/am43/cover/am43_cover.cpp +4 -2
- esphome/components/analog_threshold/analog_threshold_binary_sensor.cpp +4 -2
- esphome/components/apds9306/apds9306.cpp +8 -5
- esphome/components/apds9960/apds9960.cpp +2 -2
- esphome/components/api/__init__.py +5 -0
- esphome/components/api/api_connection.cpp +712 -358
- esphome/components/api/api_connection.h +343 -284
- esphome/components/api/api_frame_helper.cpp +349 -344
- esphome/components/api/api_frame_helper.h +121 -94
- esphome/components/api/api_pb2.cpp +2 -0
- esphome/components/api/api_pb2.h +637 -1
- esphome/components/api/api_pb2_service.cpp +12 -688
- esphome/components/api/api_pb2_service.h +53 -207
- esphome/components/api/api_server.cpp +71 -29
- esphome/components/api/api_server.h +9 -0
- esphome/components/api/client.py +5 -2
- esphome/components/api/homeassistant_service.h +1 -1
- esphome/components/api/list_entities.cpp +1 -1
- esphome/components/api/proto.cpp +1 -0
- esphome/components/api/proto.h +4 -3
- esphome/components/api/subscribe_state.cpp +8 -16
- esphome/components/as3935/as3935.cpp +3 -3
- esphome/components/as5600/as5600.cpp +9 -7
- esphome/components/as7341/as7341.cpp +7 -5
- esphome/components/at581x/at581x.cpp +13 -10
- esphome/components/atm90e26/atm90e26.cpp +2 -2
- esphome/components/atm90e32/atm90e32.cpp +3 -3
- esphome/components/axs15231/touchscreen/axs15231_touchscreen.cpp +5 -3
- esphome/components/bang_bang/bang_bang_climate.cpp +8 -5
- esphome/components/bedjet/bedjet_hub.cpp +6 -4
- esphome/components/beken_spi_led_strip/led_strip.cpp +11 -7
- esphome/components/bh1750/bh1750.cpp +2 -2
- esphome/components/binary_sensor/__init__.py +1 -0
- esphome/components/binary_sensor/automation.cpp +1 -2
- esphome/components/bl0906/bl0906.cpp +1 -1
- esphome/components/bl0942/bl0942.cpp +11 -8
- esphome/components/bl0942/sensor.py +1 -1
- esphome/components/ble_client/__init__.py +5 -1
- esphome/components/ble_client/output/ble_binary_output.cpp +6 -3
- esphome/components/ble_client/sensor/ble_sensor.cpp +9 -6
- esphome/components/ble_client/text_sensor/ble_text_sensor.cpp +8 -5
- esphome/components/bluetooth_proxy/__init__.py +5 -1
- esphome/components/bluetooth_proxy/bluetooth_connection.cpp +5 -5
- esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +16 -14
- esphome/components/bme280_base/bme280_base.cpp +3 -3
- esphome/components/bme680/bme680.cpp +3 -3
- esphome/components/bme680/sensor.py +2 -2
- esphome/components/bme680_bsec/bme680_bsec.cpp +11 -7
- esphome/components/bme680_bsec/sensor.py +7 -3
- esphome/components/bme68x_bsec2/__init__.py +6 -5
- esphome/components/bme68x_bsec2/bme68x_bsec2.cpp +17 -13
- esphome/components/bme68x_bsec2/sensor.py +4 -4
- esphome/components/bme68x_bsec2_i2c/bme68x_bsec2_i2c.cpp +1 -0
- esphome/components/bmi160/bmi160.cpp +11 -11
- esphome/components/bmp085/bmp085.cpp +2 -2
- esphome/components/bmp280_base/bmp280_base.cpp +3 -3
- esphome/components/bmp3xx_base/bmp3xx_base.cpp +13 -13
- esphome/components/bmp581/bmp581.cpp +33 -27
- esphome/components/bp1658cj/bp1658cj.cpp +5 -3
- esphome/components/bp5758d/bp5758d.cpp +1 -1
- esphome/components/button/__init__.py +1 -0
- esphome/components/canbus/canbus.cpp +1 -1
- esphome/components/cap1188/cap1188.cpp +6 -4
- esphome/components/captive_portal/captive_portal.cpp +1 -1
- esphome/components/ccs811/ccs811.cpp +3 -2
- esphome/components/cd74hc4067/cd74hc4067.cpp +1 -1
- esphome/components/ch422g/ch422g.cpp +2 -2
- esphome/components/chsc6x/chsc6x_touchscreen.cpp +6 -4
- esphome/components/climate/__init__.py +1 -0
- esphome/components/climate/climate.cpp +12 -7
- esphome/components/climate/climate.h +1 -1
- esphome/components/climate_ir/climate_ir.cpp +7 -4
- esphome/components/cm1106/__init__.py +1 -0
- esphome/components/cm1106/cm1106.cpp +112 -0
- esphome/components/cm1106/cm1106.h +40 -0
- esphome/components/cm1106/sensor.py +72 -0
- esphome/components/const/__init__.py +1 -0
- esphome/components/cover/__init__.py +1 -0
- esphome/components/cs5460a/cs5460a.cpp +16 -11
- esphome/components/cse7761/cse7761.cpp +2 -2
- esphome/components/cse7766/cse7766.cpp +0 -5
- esphome/components/cse7766/cse7766.h +5 -1
- esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +1 -1
- esphome/components/cst816/touchscreen/cst816_touchscreen.cpp +6 -3
- esphome/components/current_based/current_based_cover.cpp +4 -2
- esphome/components/dac7678/dac7678_output.cpp +4 -4
- esphome/components/dallas_temp/dallas_temp.cpp +2 -3
- esphome/components/daly_bms/daly_bms.cpp +2 -1
- esphome/components/dashboard_import/__init__.py +1 -2
- esphome/components/datetime/__init__.py +3 -1
- esphome/components/debug/debug_component.cpp +1 -1
- esphome/components/debug/debug_component.h +1 -1
- esphome/components/debug/debug_esp32.cpp +4 -2
- esphome/components/deep_sleep/deep_sleep_component.cpp +11 -5
- esphome/components/deep_sleep/deep_sleep_esp32.cpp +7 -5
- esphome/components/demo/__init__.py +206 -0
- esphome/components/demo/demo_alarm_control_panel.h +65 -0
- esphome/components/demo/demo_button.h +15 -0
- esphome/components/demo/demo_date.h +34 -0
- esphome/components/demo/demo_datetime.h +40 -0
- esphome/components/demo/demo_lock.h +17 -0
- esphome/components/demo/demo_select.h +15 -0
- esphome/components/demo/demo_text.h +18 -0
- esphome/components/demo/demo_time.h +34 -0
- esphome/components/demo/demo_valve.h +54 -0
- esphome/components/dfrobot_sen0395/commands.cpp +3 -3
- esphome/components/dht/dht.cpp +29 -50
- esphome/components/dht12/dht12.cpp +2 -2
- esphome/components/display/display.h +5 -3
- esphome/components/dps310/dps310.cpp +7 -5
- esphome/components/ds1307/ds1307.cpp +2 -2
- esphome/components/dsmr/dsmr.cpp +5 -3
- esphome/components/duty_cycle/duty_cycle_sensor.cpp +2 -2
- esphome/components/duty_time/duty_time_sensor.cpp +5 -3
- esphome/components/ee895/ee895.cpp +3 -3
- esphome/components/ektf2232/touchscreen/ektf2232.cpp +1 -1
- esphome/components/emc2101/emc2101.cpp +11 -9
- esphome/components/ens160_base/ens160_base.cpp +2 -2
- esphome/components/ens210/ens210.cpp +2 -2
- esphome/components/es7210/es7210.cpp +6 -4
- esphome/components/es7243e/es7243e.cpp +1 -1
- esphome/components/es8156/es8156.cpp +1 -1
- esphome/components/es8311/es8311.cpp +8 -6
- esphome/components/es8388/__init__.py +0 -0
- esphome/components/es8388/audio_dac.py +26 -0
- esphome/components/es8388/es8388.cpp +289 -0
- esphome/components/es8388/es8388.h +81 -0
- esphome/components/es8388/es8388_const.h +83 -0
- esphome/components/es8388/select/__init__.py +47 -0
- esphome/components/es8388/select/adc_input_mic_select.cpp +12 -0
- esphome/components/es8388/select/adc_input_mic_select.h +15 -0
- esphome/components/es8388/select/dac_output_select.cpp +12 -0
- esphome/components/es8388/select/dac_output_select.h +15 -0
- esphome/components/esp32/__init__.py +88 -20
- esphome/components/esp32/boards.py +208 -125
- esphome/components/esp32/const.py +6 -0
- esphome/components/esp32/gpio.py +14 -1
- esphome/components/esp32/gpio_esp32_c5.py +45 -0
- esphome/components/esp32/gpio_esp32_p4.py +43 -0
- esphome/components/esp32/preferences.cpp +7 -7
- esphome/components/esp32_ble/__init__.py +115 -0
- esphome/components/esp32_ble/ble.cpp +11 -9
- esphome/components/esp32_ble/ble_uuid.h +1 -1
- esphome/components/esp32_ble_client/ble_client_base.cpp +4 -2
- esphome/components/esp32_ble_server/__init__.py +4 -1
- esphome/components/esp32_ble_server/ble_characteristic.cpp +1 -0
- esphome/components/esp32_ble_server/ble_server.h +0 -1
- esphome/components/esp32_ble_tracker/__init__.py +6 -2
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +12 -9
- esphome/components/esp32_camera/esp32_camera.cpp +35 -27
- esphome/components/esp32_camera_web_server/camera_web_server.cpp +4 -2
- esphome/components/esp32_dac/esp32_dac.cpp +2 -2
- esphome/components/esp32_improv/__init__.py +5 -1
- esphome/components/esp32_improv/esp32_improv_component.cpp +2 -2
- esphome/components/esp32_rmt_led_strip/led_strip.cpp +11 -7
- esphome/components/esp32_rmt_led_strip/light.py +5 -1
- esphome/components/esp32_touch/esp32_touch.cpp +12 -8
- esphome/components/esp8266/preferences.cpp +6 -6
- esphome/components/esp8266_pwm/esp8266_pwm.cpp +3 -3
- esphome/components/esp_ldo/__init__.py +91 -0
- esphome/components/esp_ldo/esp_ldo.cpp +43 -0
- esphome/components/esp_ldo/esp_ldo.h +43 -0
- esphome/components/esphome/ota/ota_esphome.cpp +15 -8
- esphome/components/ethernet/ethernet_component.cpp +38 -26
- esphome/components/ethernet/ethernet_component.h +1 -1
- esphome/components/event/__init__.py +1 -0
- esphome/components/exposure_notifications/exposure_notifications.cpp +1 -1
- esphome/components/ezo/ezo.cpp +1 -1
- esphome/components/ezo_pmp/ezo_pmp.cpp +1 -1
- esphome/components/factory_reset/button/factory_reset_button.cpp +1 -1
- esphome/components/factory_reset/switch/factory_reset_switch.cpp +1 -1
- esphome/components/fan/__init__.py +1 -0
- esphome/components/fan/fan.cpp +4 -2
- esphome/components/fastled_base/fastled_light.cpp +7 -5
- esphome/components/fingerprint_grow/fingerprint_grow.cpp +8 -6
- esphome/components/fs3000/fs3000.cpp +1 -1
- esphome/components/ft5x06/touchscreen/ft5x06_touchscreen.cpp +7 -4
- esphome/components/ft63x6/ft63x6.cpp +5 -3
- esphome/components/gcja5/gcja5.cpp +0 -12
- esphome/components/gcja5/gcja5.h +8 -3
- esphome/components/gdk101/gdk101.cpp +2 -2
- esphome/components/globals/globals_component.h +13 -10
- esphome/components/gp2y1010au0f/gp2y1010au0f.cpp +4 -2
- esphome/components/gp8403/gp8403.cpp +4 -2
- esphome/components/gp8403/output/gp8403_output.cpp +4 -2
- esphome/components/gpio/one_wire/gpio_one_wire.cpp +2 -2
- esphome/components/gpio/output/gpio_binary_output.cpp +1 -1
- esphome/components/gpio/switch/gpio_switch.cpp +1 -1
- esphome/components/graphical_display_menu/graphical_display_menu.cpp +12 -8
- esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.cpp +5 -6
- esphome/components/grove_tb6612fng/grove_tb6612fng.cpp +1 -1
- esphome/components/grove_tb6612fng/grove_tb6612fng.h +1 -1
- esphome/components/growatt_solar/growatt_solar.cpp +6 -3
- esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +1 -1
- esphome/components/haier/haier_base.cpp +2 -2
- esphome/components/haier/hon_climate.cpp +13 -6
- esphome/components/havells_solar/havells_solar.cpp +5 -2
- esphome/components/hbridge/switch/hbridge_switch.cpp +1 -1
- esphome/components/hdc1080/hdc1080.cpp +2 -2
- esphome/components/he60r/he60r.cpp +4 -2
- esphome/components/hlw8012/hlw8012.cpp +6 -4
- esphome/components/hm3301/hm3301.cpp +2 -2
- esphome/components/hmc5883l/hmc5883l.cpp +2 -2
- esphome/components/homeassistant/time/homeassistant_time.cpp +4 -2
- esphome/components/honeywell_hih_i2c/honeywell_hih.cpp +4 -4
- esphome/components/honeywellabp/honeywellabp.cpp +4 -2
- esphome/components/honeywellabp2_i2c/honeywellabp2.cpp +8 -6
- esphome/components/hte501/hte501.cpp +3 -2
- esphome/components/http_request/__init__.py +2 -2
- esphome/components/http_request/http_request.cpp +7 -5
- esphome/components/http_request/http_request_idf.cpp +4 -2
- esphome/components/http_request/ota/ota_http_request.cpp +1 -1
- esphome/components/htu21d/htu21d.cpp +2 -2
- esphome/components/htu31d/htu31d.cpp +2 -2
- esphome/components/hx711/hx711.cpp +2 -2
- esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +5 -3
- esphome/components/hyt271/hyt271.cpp +2 -2
- esphome/components/i2c/i2c_bus_arduino.cpp +14 -11
- esphome/components/i2c/i2c_bus_esp_idf.cpp +13 -11
- esphome/components/i2s_audio/__init__.py +2 -0
- esphome/components/i2s_audio/i2s_audio.cpp +3 -4
- esphome/components/i2s_audio/i2s_audio.h +1 -1
- esphome/components/i2s_audio/media_player/__init__.py +1 -1
- esphome/components/i2s_audio/media_player/i2s_audio_media_player.cpp +5 -3
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +1 -1
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +1 -1
- esphome/components/iaqcore/iaqcore.cpp +3 -3
- esphome/components/ili9xxx/ili9xxx_display.cpp +12 -7
- esphome/components/ili9xxx/ili9xxx_display.h +1 -1
- esphome/components/image/image.cpp +1 -0
- esphome/components/ina219/ina219.cpp +2 -2
- esphome/components/ina226/ina226.cpp +8 -5
- esphome/components/ina260/ina260.cpp +1 -1
- esphome/components/ina2xx_base/ina2xx_base.cpp +13 -9
- esphome/components/ina3221/ina3221.cpp +2 -2
- esphome/components/inkplate6/display.py +12 -2
- esphome/components/inkplate6/inkplate.cpp +13 -9
- esphome/components/inkplate6/inkplate.h +7 -6
- esphome/components/integration/integration_sensor.cpp +1 -1
- esphome/components/internal_temperature/internal_temperature.cpp +4 -4
- esphome/components/json/json_util.cpp +4 -5
- esphome/components/kamstrup_kmp/kamstrup_kmp.cpp +1 -1
- esphome/components/key_collector/key_collector.cpp +4 -2
- esphome/components/kmeteriso/kmeteriso.cpp +2 -1
- esphome/components/kuntze/kuntze.cpp +4 -2
- esphome/components/lc709203f/__init__.py +1 -0
- esphome/components/lc709203f/lc709203f.cpp +299 -0
- esphome/components/lc709203f/lc709203f.h +55 -0
- esphome/components/lc709203f/sensor.py +93 -0
- esphome/components/lcd_base/lcd_display.cpp +2 -2
- esphome/components/lcd_gpio/gpio_lcd_display.cpp +5 -3
- esphome/components/lcd_menu/lcd_menu.cpp +6 -4
- esphome/components/lcd_pcf8574/pcf8574_display.cpp +6 -4
- esphome/components/ld2410/ld2410.cpp +6 -7
- esphome/components/ld2420/ld2420.cpp +9 -7
- esphome/components/ld2450/ld2450.cpp +6 -4
- esphome/components/ld2450/sensor.py +2 -2
- esphome/components/ledc/ledc_output.cpp +32 -28
- esphome/components/libretiny/const.py +1 -1
- esphome/components/libretiny/preferences.cpp +6 -7
- esphome/components/light/__init__.py +2 -1
- esphome/components/light/esp_hsv_color.h +1 -1
- esphome/components/light/light_state.cpp +9 -5
- esphome/components/light/light_transformer.h +1 -1
- esphome/components/lightwaverf/LwTx.cpp +1 -1
- esphome/components/lightwaverf/lightwaverf.cpp +1 -1
- esphome/components/lilygo_t5_47/touchscreen/lilygo_t5_47_touchscreen.cpp +1 -1
- esphome/components/lock/__init__.py +1 -0
- esphome/components/lock/lock.h +1 -1
- esphome/components/logger/__init__.py +6 -0
- esphome/components/logger/logger.cpp +9 -5
- esphome/components/logger/logger_esp32.cpp +5 -5
- esphome/components/ltr390/ltr390.cpp +8 -5
- esphome/components/ltr501/ltr501.cpp +19 -14
- esphome/components/ltr_als_ps/ltr_als_ps.cpp +20 -13
- esphome/components/lvgl/__init__.py +2 -2
- esphome/components/lvgl/automation.py +5 -4
- esphome/components/lvgl/defines.py +0 -2
- esphome/components/lvgl/lv_validation.py +1 -3
- esphome/components/lvgl/lvcode.py +7 -8
- esphome/components/lvgl/lvgl_esphome.cpp +26 -10
- esphome/components/lvgl/schemas.py +22 -23
- esphome/components/lvgl/trigger.py +8 -3
- esphome/components/lvgl/widgets/__init__.py +2 -2
- esphome/components/lvgl/widgets/canvas.py +9 -3
- esphome/components/lvgl/widgets/line.py +2 -1
- esphome/components/lvgl/widgets/tabview.py +7 -0
- esphome/components/m5stack_8angle/m5stack_8angle.cpp +3 -3
- esphome/components/matrix_keypad/matrix_keypad.cpp +2 -2
- esphome/components/max17043/max17043.cpp +2 -2
- esphome/components/max31855/max31855.cpp +2 -1
- esphome/components/max31856/max31856.cpp +9 -11
- esphome/components/max31865/max31865.cpp +6 -4
- esphome/components/max44009/max44009.cpp +2 -2
- esphome/components/max6675/max6675.cpp +1 -1
- esphome/components/max6956/max6956.cpp +5 -3
- esphome/components/max7219/max7219.cpp +8 -6
- esphome/components/max7219digit/automation.h +52 -0
- esphome/components/max7219digit/display.py +93 -1
- esphome/components/max7219digit/max7219digit.cpp +16 -13
- esphome/components/max9611/max9611.cpp +9 -6
- esphome/components/mcp23008/mcp23008.cpp +1 -1
- esphome/components/mcp23016/mcp23016.cpp +1 -1
- esphome/components/mcp23017/mcp23017.cpp +1 -1
- esphome/components/mcp23s08/mcp23s08.cpp +1 -1
- esphome/components/mcp23s17/mcp23s17.cpp +1 -1
- esphome/components/mcp3008/mcp3008.cpp +1 -1
- esphome/components/mcp3008/sensor/mcp3008_sensor.cpp +5 -3
- esphome/components/mcp3204/mcp3204.cpp +1 -1
- esphome/components/mcp4461/mcp4461.cpp +2 -2
- esphome/components/mcp4725/mcp4725.cpp +2 -2
- esphome/components/mcp4728/mcp4728.cpp +2 -2
- esphome/components/mcp9600/mcp9600.cpp +1 -1
- esphome/components/mcp9808/mcp9808.cpp +4 -4
- esphome/components/mdns/mdns_component.cpp +8 -2
- esphome/components/mdns/mdns_component.h +3 -1
- esphome/components/mdns/mdns_esp32.cpp +2 -2
- esphome/components/media_player/__init__.py +1 -0
- esphome/components/micro_wake_word/micro_wake_word.cpp +1 -1
- esphome/components/micro_wake_word/streaming_model.cpp +10 -6
- esphome/components/micronova/micronova.h +2 -2
- esphome/components/mics_4514/mics_4514.cpp +2 -2
- esphome/components/midea/air_conditioner.cpp +7 -5
- esphome/components/midea_ir/midea_ir.cpp +1 -1
- esphome/components/mipi_spi/mipi_spi.cpp +24 -15
- esphome/components/mixer/speaker/mixer_speaker.cpp +8 -4
- esphome/components/mlx90393/sensor_mlx90393.cpp +2 -2
- esphome/components/mlx90614/mlx90614.cpp +4 -3
- esphome/components/mmc5603/mmc5603.cpp +2 -2
- esphome/components/mmc5983/mmc5983.cpp +1 -1
- esphome/components/modbus/modbus.cpp +7 -5
- esphome/components/modbus_controller/modbus_controller.cpp +6 -4
- esphome/components/modbus_controller/output/modbus_output.cpp +10 -6
- esphome/components/modbus_controller/switch/__init__.py +6 -2
- esphome/components/modbus_controller/switch/modbus_switch.cpp +4 -0
- esphome/components/modbus_controller/switch/modbus_switch.h +3 -0
- esphome/components/mpl3115a2/mpl3115a2.cpp +3 -2
- esphome/components/mpr121/mpr121.cpp +2 -2
- esphome/components/mpu6050/mpu6050.cpp +6 -6
- esphome/components/mpu6886/mpu6886.cpp +6 -6
- esphome/components/mqtt/mqtt_alarm_control_panel.cpp +7 -3
- esphome/components/mqtt/mqtt_backend_esp32.cpp +1 -1
- esphome/components/mqtt/mqtt_client.cpp +31 -24
- esphome/components/mqtt/mqtt_component.cpp +2 -2
- esphome/components/mqtt/mqtt_cover.cpp +8 -4
- esphome/components/mqtt/mqtt_fan.cpp +12 -6
- esphome/components/mqtt/mqtt_valve.cpp +4 -2
- esphome/components/ms5611/ms5611.cpp +2 -2
- esphome/components/ms8607/ms8607.cpp +2 -2
- esphome/components/msa3xx/msa3xx.cpp +16 -12
- esphome/components/my9231/my9231.cpp +7 -5
- esphome/components/nau7802/nau7802.cpp +6 -4
- esphome/components/neopixelbus/neopixelbus_light.h +2 -2
- esphome/components/network/ip_address.h +1 -1
- esphome/components/network/util.cpp +13 -0
- esphome/components/nextion/base_component.py +2 -0
- esphome/components/nextion/binary_sensor/nextion_binarysensor.cpp +2 -3
- esphome/components/nextion/display.py +34 -22
- esphome/components/nextion/nextion.cpp +182 -143
- esphome/components/nextion/nextion.h +36 -0
- esphome/components/nextion/nextion_commands.cpp +3 -3
- esphome/components/nextion/nextion_upload_arduino.cpp +58 -61
- esphome/components/nextion/nextion_upload_idf.cpp +69 -72
- esphome/components/nextion/sensor/nextion_sensor.cpp +4 -4
- esphome/components/nextion/switch/nextion_switch.cpp +2 -2
- esphome/components/nextion/text_sensor/nextion_textsensor.cpp +2 -2
- esphome/components/nfc/nci_message.h +1 -1
- esphome/components/nfc/ndef_record.h +1 -1
- esphome/components/nfc/ndef_record_text.h +1 -1
- esphome/components/nfc/ndef_record_uri.h +1 -1
- esphome/components/nfc/nfc.h +1 -1
- esphome/components/nfc/nfc_tag.h +1 -1
- esphome/components/noblex/noblex.cpp +1 -1
- esphome/components/npi19/npi19.cpp +5 -7
- esphome/components/number/__init__.py +11 -0
- esphome/components/online_image/__init__.py +13 -1
- esphome/components/online_image/online_image.cpp +26 -4
- esphome/components/online_image/online_image.h +21 -4
- esphome/components/opentherm/generate.py +3 -3
- esphome/components/opentherm/hub.cpp +11 -7
- esphome/components/opentherm/number/number.cpp +5 -3
- esphome/components/opentherm/opentherm.h +1 -1
- esphome/components/opentherm/schema.py +13 -13
- esphome/components/opentherm/validate.py +1 -1
- esphome/components/openthread/__init__.py +146 -0
- esphome/components/openthread/const.py +10 -0
- esphome/components/openthread/openthread.cpp +206 -0
- esphome/components/openthread/openthread.h +68 -0
- esphome/components/openthread/openthread_esp.cpp +164 -0
- esphome/components/openthread/tlv.py +58 -0
- esphome/components/openthread_info/__init__.py +0 -0
- esphome/components/openthread_info/openthread_info_text_sensor.cpp +24 -0
- esphome/components/openthread_info/openthread_info_text_sensor.h +218 -0
- esphome/components/openthread_info/text_sensor.py +105 -0
- esphome/components/output/float_output.cpp +1 -1
- esphome/components/output/switch/output_switch.cpp +1 -1
- esphome/components/packet_transport/packet_transport.cpp +6 -4
- esphome/components/pca6416a/pca6416a.cpp +2 -2
- esphome/components/pca9554/pca9554.cpp +6 -4
- esphome/components/pca9685/pca9685_output.cpp +12 -8
- esphome/components/pcd8544/pcd_8544.cpp +1 -1
- esphome/components/pcf85063/pcf85063.cpp +2 -2
- esphome/components/pcf8563/pcf8563.cpp +2 -2
- esphome/components/pcf8574/pcf8574.cpp +2 -2
- esphome/components/pid/pid_climate.cpp +8 -5
- esphome/components/pid/pid_climate.h +1 -1
- esphome/components/pid/sensor/pid_climate_sensor.cpp +1 -1
- esphome/components/pipsolar/output/pipsolar_output.cpp +1 -1
- esphome/components/pipsolar/pipsolar.cpp +3 -3
- esphome/components/pm1006/pm1006.cpp +3 -7
- esphome/components/pm1006/pm1006.h +4 -1
- esphome/components/pm2005/pm2005.cpp +12 -13
- esphome/components/pm2005/sensor.py +1 -1
- esphome/components/pmsa003i/pmsa003i.cpp +2 -2
- esphome/components/pmsx003/pmsx003.cpp +0 -4
- esphome/components/pmsx003/pmsx003.h +5 -2
- esphome/components/pmwcs3/pmwcs3.cpp +9 -13
- esphome/components/pmwcs3/pmwcs3.h +0 -1
- esphome/components/pn532/pn532.cpp +7 -7
- esphome/components/pn532/pn532.h +1 -1
- esphome/components/pn532_spi/pn532_spi.cpp +1 -1
- esphome/components/pn7150/pn7150.cpp +4 -4
- esphome/components/pn7160/pn7160.cpp +4 -4
- esphome/components/power_supply/power_supply.cpp +6 -4
- esphome/components/power_supply/power_supply.h +1 -1
- esphome/components/psram/__init__.py +59 -35
- esphome/components/pulse_counter/pulse_counter_sensor.cpp +7 -4
- esphome/components/pvvx_mithermometer/display/pvvx_display.cpp +8 -5
- esphome/components/pylontech/pylontech.cpp +2 -2
- esphome/components/pylontech/sensor/pylontech_sensor.cpp +4 -2
- esphome/components/pylontech/text_sensor/pylontech_text_sensor.cpp +4 -2
- esphome/components/pzemac/pzemac.cpp +4 -2
- esphome/components/pzemdc/pzemdc.cpp +4 -2
- esphome/components/qmc5883l/qmc5883l.cpp +2 -2
- esphome/components/qmp6988/qmp6988.cpp +2 -2
- esphome/components/qmp6988/qmp6988.h +1 -1
- esphome/components/qr_code/qr_code.cpp +5 -3
- esphome/components/qspi_dbi/qspi_dbi.cpp +1 -1
- esphome/components/qwiic_pir/qwiic_pir.cpp +26 -28
- esphome/components/rc522/rc522.cpp +5 -5
- esphome/components/rdm6300/rdm6300.cpp +1 -0
- esphome/components/remote_receiver/__init__.py +10 -2
- esphome/components/remote_receiver/remote_receiver_esp32.cpp +22 -12
- esphome/components/remote_receiver/remote_receiver_esp8266.cpp +10 -7
- esphome/components/remote_receiver/remote_receiver_libretiny.cpp +10 -7
- esphome/components/remote_transmitter/__init__.py +10 -2
- esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +10 -6
- esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +5 -3
- esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +5 -3
- esphome/components/resistance/resistance_sensor.cpp +6 -3
- esphome/components/restart/button/restart_button.cpp +1 -1
- esphome/components/restart/switch/restart_switch.cpp +1 -1
- esphome/components/rotary_encoder/rotary_encoder.cpp +2 -2
- esphome/components/rp2040/__init__.py +7 -0
- esphome/components/rp2040/core.cpp +8 -1
- esphome/components/rp2040/preferences.cpp +3 -3
- esphome/components/rp2040_pio_led_strip/led_strip.cpp +11 -8
- esphome/components/rp2040_pio_led_strip/light.py +1 -1
- esphome/components/rp2040_pwm/rp2040_pwm.cpp +1 -1
- esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +1 -1
- esphome/components/rtttl/rtttl.cpp +11 -9
- esphome/components/safe_mode/button/safe_mode_button.cpp +1 -1
- esphome/components/safe_mode/safe_mode.cpp +9 -8
- esphome/components/safe_mode/switch/safe_mode_switch.cpp +1 -1
- esphome/components/scd30/scd30.cpp +11 -8
- esphome/components/scd4x/scd4x.cpp +12 -8
- esphome/components/sdl/display.py +40 -0
- esphome/components/sdl/sdl_esphome.cpp +2 -2
- esphome/components/sdl/sdl_esphome.h +8 -0
- esphome/components/sdm_meter/sdm_meter.cpp +5 -2
- esphome/components/sdp3x/sdp3x.cpp +11 -11
- esphome/components/sds011/sds011.cpp +5 -6
- esphome/components/sds011/sds011.h +4 -1
- esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.cpp +3 -2
- esphome/components/seeed_mr60bha2/seeed_mr60bha2.cpp +1 -0
- esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp +3 -2
- esphome/components/selec_meter/selec_meter.cpp +5 -2
- esphome/components/select/__init__.py +1 -0
- esphome/components/sen0321/sen0321.cpp +2 -2
- esphome/components/sen21231/sen21231.cpp +1 -1
- esphome/components/sen5x/sen5x.cpp +10 -7
- esphome/components/sensirion_common/i2c_sensirion.cpp +2 -1
- esphome/components/sensirion_common/i2c_sensirion.h +1 -0
- esphome/components/sensor/__init__.py +11 -1
- esphome/components/sensor/filter.h +1 -1
- esphome/components/sensor/sensor.h +9 -5
- esphome/components/servo/servo.cpp +12 -9
- esphome/components/servo/servo.h +1 -1
- esphome/components/sfa30/sfa30.cpp +1 -1
- esphome/components/sgp30/sgp30.cpp +10 -8
- esphome/components/sgp4x/sgp4x.cpp +49 -61
- esphome/components/sgp4x/sgp4x.h +0 -1
- esphome/components/shelly_dimmer/shelly_dimmer.cpp +11 -7
- esphome/components/sht3xd/sht3xd.cpp +1 -1
- esphome/components/sht4x/sht4x.cpp +2 -2
- esphome/components/shtcx/shtcx.cpp +13 -16
- esphome/components/shutdown/button/shutdown_button.cpp +1 -1
- esphome/components/shutdown/switch/shutdown_switch.cpp +1 -1
- esphome/components/sim800l/sim800l.cpp +2 -2
- esphome/components/slow_pwm/slow_pwm_output.cpp +4 -2
- esphome/components/sm16716/sm16716.cpp +1 -1
- esphome/components/sm2135/sm2135.cpp +1 -1
- esphome/components/sm2235/sm2235.cpp +5 -3
- esphome/components/sm2335/sm2335.cpp +5 -3
- esphome/components/sml/sml.cpp +1 -1
- esphome/components/sn74hc165/sn74hc165.cpp +1 -2
- esphome/components/sn74hc595/sn74hc595.cpp +1 -2
- esphome/components/sntp/sntp_component.cpp +1 -1
- esphome/components/socket/__init__.py +2 -0
- esphome/components/socket/bsd_sockets_impl.cpp +51 -7
- esphome/components/socket/lwip_raw_tcp_impl.cpp +5 -0
- esphome/components/socket/lwip_sockets_impl.cpp +51 -7
- esphome/components/socket/socket.cpp +31 -0
- esphome/components/socket/socket.h +27 -1
- esphome/components/sonoff_d1/sonoff_d1.cpp +7 -4
- esphome/components/sonoff_d1/sonoff_d1.h +2 -2
- esphome/components/sound_level/sound_level.cpp +4 -2
- esphome/components/speaker/media_player/__init__.py +3 -0
- esphome/components/speaker/media_player/speaker_media_player.cpp +1 -3
- esphome/components/speaker/media_player/speaker_media_player.h +6 -0
- esphome/components/spi/__init__.py +10 -2
- esphome/components/spi/spi.cpp +4 -4
- esphome/components/spi_device/spi_device.cpp +1 -2
- esphome/components/sprinkler/sprinkler.cpp +9 -6
- esphome/components/sps30/sps30.cpp +16 -15
- esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
- esphome/components/ssd1306_i2c/ssd1306_i2c.cpp +11 -8
- esphome/components/ssd1306_spi/ssd1306_spi.cpp +10 -7
- esphome/components/ssd1322_base/ssd1322_base.cpp +1 -1
- esphome/components/ssd1322_spi/ssd1322_spi.cpp +1 -1
- esphome/components/ssd1325_base/ssd1325_base.cpp +1 -1
- esphome/components/ssd1325_spi/ssd1325_spi.cpp +1 -1
- esphome/components/ssd1327_base/ssd1327_base.cpp +1 -1
- esphome/components/ssd1327_i2c/ssd1327_i2c.cpp +2 -2
- esphome/components/ssd1327_spi/ssd1327_spi.cpp +1 -1
- esphome/components/ssd1331_base/ssd1331_base.cpp +1 -1
- esphome/components/ssd1331_spi/ssd1331_spi.cpp +1 -1
- esphome/components/ssd1351_base/ssd1351_base.cpp +1 -1
- esphome/components/ssd1351_spi/ssd1351_spi.cpp +1 -1
- esphome/components/st7567_base/st7567_base.cpp +3 -3
- esphome/components/st7567_i2c/st7567_i2c.cpp +7 -5
- esphome/components/st7567_spi/st7567_spi.cpp +1 -1
- esphome/components/st7701s/st7701s.cpp +4 -2
- esphome/components/st7735/st7735.cpp +3 -3
- esphome/components/st7789v/st7789v.cpp +10 -7
- esphome/components/st7920/st7920.cpp +6 -4
- esphome/components/statsd/statsd.cpp +9 -5
- esphome/components/status_led/light/status_led_light.cpp +1 -1
- esphome/components/status_led/status_led.cpp +1 -1
- esphome/components/stepper/stepper.h +5 -3
- esphome/components/sts3x/sts3x.cpp +2 -2
- esphome/components/switch/__init__.py +1 -0
- esphome/components/switch/switch.cpp +18 -12
- esphome/components/switch/switch.h +1 -1
- esphome/components/sx1509/__init__.py +53 -20
- esphome/components/sx1509/sx1509.cpp +29 -5
- esphome/components/sx1509/sx1509.h +9 -1
- esphome/components/t6615/t6615.cpp +1 -0
- esphome/components/tc74/tc74.cpp +1 -1
- esphome/components/tca9548a/tca9548a.cpp +1 -1
- esphome/components/tca9555/tca9555.cpp +2 -2
- esphome/components/tcs34725/tcs34725.cpp +4 -4
- esphome/components/tee501/tee501.cpp +3 -2
- esphome/components/tem3200/tem3200.cpp +5 -6
- esphome/components/template/alarm_control_panel/__init__.py +6 -0
- esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +38 -12
- esphome/components/template/alarm_control_panel/template_alarm_control_panel.h +3 -1
- esphome/components/template/cover/template_cover.cpp +1 -1
- esphome/components/template/select/template_select.cpp +6 -4
- esphome/components/template/text/template_text.cpp +2 -3
- esphome/components/template/valve/template_valve.cpp +5 -3
- esphome/components/text/__init__.py +10 -11
- esphome/components/text_sensor/__init__.py +1 -0
- esphome/components/thermostat/thermostat_climate.cpp +67 -43
- esphome/components/time/__init__.py +1 -2
- esphome/components/time_based/time_based_cover.cpp +4 -2
- esphome/components/tlc59208f/tlc59208f_output.cpp +8 -6
- esphome/components/tm1621/tm1621.cpp +3 -3
- esphome/components/tm1637/tm1637.cpp +9 -7
- esphome/components/tm1638/tm1638.cpp +7 -5
- esphome/components/tm1651/tm1651.cpp +2 -2
- esphome/components/tmp102/tmp102.cpp +1 -3
- esphome/components/tmp102/tmp102.h +0 -3
- esphome/components/tmp1075/tmp1075.cpp +12 -9
- esphome/components/tmp117/tmp117.cpp +2 -2
- esphome/components/tof10120/tof10120_sensor.cpp +2 -2
- esphome/components/tormatic/tormatic_cover.cpp +4 -2
- esphome/components/tsl2561/tsl2561.cpp +7 -5
- esphome/components/tsl2591/tsl2591.cpp +25 -27
- esphome/components/tt21100/touchscreen/tt21100.cpp +1 -1
- esphome/components/ttp229_bsf/ttp229_bsf.cpp +1 -1
- esphome/components/ttp229_lsf/ttp229_lsf.cpp +2 -2
- esphome/components/tuya/select/tuya_select.cpp +5 -3
- esphome/components/tx20/tx20.cpp +3 -3
- esphome/components/uart/__init__.py +4 -5
- esphome/components/uart/button/uart_button.cpp +1 -1
- esphome/components/uart/switch/uart_switch.cpp +2 -2
- esphome/components/uart/uart.cpp +2 -2
- esphome/components/uart/uart_component_esp32_arduino.cpp +8 -6
- esphome/components/uart/uart_component_esp8266.cpp +9 -7
- esphome/components/uart/uart_component_esp_idf.cpp +9 -7
- esphome/components/uart/uart_component_host.cpp +11 -8
- esphome/components/uart/uart_component_libretiny.cpp +8 -6
- esphome/components/uart/uart_component_rp2040.cpp +8 -6
- esphome/components/udp/udp_component.cpp +9 -5
- esphome/components/ufire_ec/ufire_ec.cpp +5 -3
- esphome/components/ufire_ise/ufire_ise.cpp +1 -1
- esphome/components/ultrasonic/ultrasonic_sensor.cpp +5 -3
- esphome/components/update/__init__.py +1 -0
- esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +1 -1
- esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.cpp +4 -2
- esphome/components/uponor_smatrix/uponor_smatrix.cpp +2 -1
- esphome/components/usb_host/__init__.py +64 -0
- esphome/components/usb_host/usb_host.h +116 -0
- esphome/components/usb_host/usb_host_client.cpp +394 -0
- esphome/components/usb_host/usb_host_component.cpp +35 -0
- esphome/components/usb_uart/__init__.py +134 -0
- esphome/components/usb_uart/ch34x.cpp +80 -0
- esphome/components/usb_uart/cp210x.cpp +126 -0
- esphome/components/usb_uart/usb_uart.cpp +328 -0
- esphome/components/usb_uart/usb_uart.h +151 -0
- esphome/components/valve/__init__.py +1 -0
- esphome/components/veml3235/veml3235.cpp +13 -9
- esphome/components/veml7700/veml7700.cpp +10 -6
- esphome/components/voice_assistant/voice_assistant.cpp +7 -7
- esphome/components/wake_on_lan/wake_on_lan.cpp +1 -1
- esphome/components/waveshare_epaper/waveshare_epaper.cpp +1 -1
- esphome/components/web_server/server_index_v2.h +632 -630
- esphome/components/web_server/server_index_v3.h +411 -409
- esphome/components/web_server/web_server.cpp +5 -3
- esphome/components/web_server_base/web_server_base.cpp +1 -1
- esphome/components/web_server_idf/utils.cpp +1 -1
- esphome/components/web_server_idf/web_server_idf.cpp +1 -1
- esphome/components/weikai/__init__.py +2 -0
- esphome/components/weikai/weikai.cpp +23 -21
- esphome/components/weikai_i2c/weikai_i2c.cpp +14 -9
- esphome/components/weikai_spi/weikai_spi.cpp +11 -6
- esphome/components/wiegand/wiegand.cpp +1 -1
- esphome/components/wifi/wifi_component.cpp +50 -37
- esphome/components/wifi/wifi_component.h +7 -4
- esphome/components/wifi/wifi_component_esp32_arduino.cpp +2 -2
- esphome/components/wifi/wifi_component_esp8266.cpp +3 -3
- esphome/components/wifi/wifi_component_libretiny.cpp +4 -4
- esphome/components/wireguard/wireguard.cpp +21 -21
- esphome/components/wl_134/text_sensor.py +1 -2
- esphome/components/wled/wled_light_effect.cpp +1 -1
- esphome/components/x9c/x9c.cpp +5 -3
- esphome/components/xgzp68xx/xgzp68xx.cpp +8 -6
- esphome/components/xiaomi_cgd1/xiaomi_cgd1.cpp +4 -2
- esphome/components/xiaomi_cgdk2/xiaomi_cgdk2.cpp +4 -2
- esphome/components/xiaomi_cgg1/xiaomi_cgg1.cpp +4 -2
- esphome/components/xiaomi_hhccjcy10/xiaomi_hhccjcy10.cpp +1 -1
- esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.cpp +4 -2
- esphome/components/xiaomi_lywsd03mmc/xiaomi_lywsd03mmc.cpp +4 -2
- esphome/components/xiaomi_mhoc401/xiaomi_mhoc401.cpp +4 -2
- esphome/components/xl9535/xl9535.cpp +2 -2
- esphome/components/xpt2046/touchscreen/xpt2046.cpp +12 -11
- esphome/components/xpt2046/touchscreen/xpt2046.h +2 -2
- esphome/config.py +3 -2
- esphome/config_validation.py +46 -17
- esphome/const.py +10 -1
- esphome/core/__init__.py +37 -18
- esphome/core/application.cpp +188 -5
- esphome/core/application.h +110 -0
- esphome/core/component.h +13 -0
- esphome/core/config.py +12 -0
- esphome/core/defines.h +10 -2
- esphome/core/helpers.cpp +1 -1
- esphome/core/helpers.h +4 -4
- esphome/core/log.h +2 -0
- esphome/core/log_const_en.h +4 -0
- esphome/core/scheduler.cpp +2 -2
- esphome/coroutine.py +3 -4
- esphome/cpp_generator.py +32 -32
- esphome/dashboard/core.py +2 -2
- esphome/dashboard/web_server.py +2 -2
- esphome/git.py +4 -4
- esphome/helpers.py +5 -6
- esphome/loader.py +8 -7
- esphome/log.py +7 -1
- esphome/platformio_api.py +2 -3
- esphome/storage_json.py +13 -5
- esphome/types.py +12 -13
- esphome/util.py +1 -2
- esphome/writer.py +5 -3
- esphome/yaml_util.py +6 -1
- esphome/zeroconf.py +1 -1
- {esphome-2025.5.2.dist-info → esphome-2025.6.0b1.dist-info}/METADATA +12 -11
- {esphome-2025.5.2.dist-info → esphome-2025.6.0b1.dist-info}/RECORD +715 -662
- {esphome-2025.5.2.dist-info → esphome-2025.6.0b1.dist-info}/WHEEL +1 -1
- {esphome-2025.5.2.dist-info → esphome-2025.6.0b1.dist-info}/entry_points.txt +0 -0
- {esphome-2025.5.2.dist-info → esphome-2025.6.0b1.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.5.2.dist-info → esphome-2025.6.0b1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,134 @@
|
|
1
|
+
import esphome.codegen as cg
|
2
|
+
from esphome.components.uart import (
|
3
|
+
CONF_DATA_BITS,
|
4
|
+
CONF_PARITY,
|
5
|
+
CONF_STOP_BITS,
|
6
|
+
UARTComponent,
|
7
|
+
)
|
8
|
+
from esphome.components.usb_host import register_usb_client, usb_device_schema
|
9
|
+
import esphome.config_validation as cv
|
10
|
+
from esphome.const import (
|
11
|
+
CONF_BAUD_RATE,
|
12
|
+
CONF_BUFFER_SIZE,
|
13
|
+
CONF_CHANNELS,
|
14
|
+
CONF_DEBUG,
|
15
|
+
CONF_DUMMY_RECEIVER,
|
16
|
+
CONF_ID,
|
17
|
+
)
|
18
|
+
from esphome.cpp_types import Component
|
19
|
+
|
20
|
+
AUTO_LOAD = ["uart", "usb_host", "bytebuffer"]
|
21
|
+
CODEOWNERS = ["@clydebarrow"]
|
22
|
+
|
23
|
+
usb_uart_ns = cg.esphome_ns.namespace("usb_uart")
|
24
|
+
USBUartComponent = usb_uart_ns.class_("USBUartComponent", Component)
|
25
|
+
USBUartChannel = usb_uart_ns.class_("USBUartChannel", UARTComponent)
|
26
|
+
|
27
|
+
|
28
|
+
UARTParityOptions = usb_uart_ns.enum("UARTParityOptions")
|
29
|
+
UART_PARITY_OPTIONS = {
|
30
|
+
"NONE": UARTParityOptions.UART_CONFIG_PARITY_NONE,
|
31
|
+
"EVEN": UARTParityOptions.UART_CONFIG_PARITY_EVEN,
|
32
|
+
"ODD": UARTParityOptions.UART_CONFIG_PARITY_ODD,
|
33
|
+
"MARK": UARTParityOptions.UART_CONFIG_PARITY_MARK,
|
34
|
+
"SPACE": UARTParityOptions.UART_CONFIG_PARITY_SPACE,
|
35
|
+
}
|
36
|
+
|
37
|
+
UARTStopBitsOptions = usb_uart_ns.enum("UARTStopBitsOptions")
|
38
|
+
UART_STOP_BITS_OPTIONS = {
|
39
|
+
"1": UARTStopBitsOptions.UART_CONFIG_STOP_BITS_1,
|
40
|
+
"1.5": UARTStopBitsOptions.UART_CONFIG_STOP_BITS_1_5,
|
41
|
+
"2": UARTStopBitsOptions.UART_CONFIG_STOP_BITS_2,
|
42
|
+
}
|
43
|
+
|
44
|
+
DEFAULT_BAUD_RATE = 9600
|
45
|
+
|
46
|
+
|
47
|
+
class Type:
|
48
|
+
def __init__(self, name, vid, pid, cls, max_channels=1, baud_rate_required=True):
|
49
|
+
self.name = name
|
50
|
+
cls = cls or name
|
51
|
+
self.vid = vid
|
52
|
+
self.pid = pid
|
53
|
+
self.cls = usb_uart_ns.class_(f"USBUartType{cls}", USBUartComponent)
|
54
|
+
self.max_channels = max_channels
|
55
|
+
self.baud_rate_required = baud_rate_required
|
56
|
+
|
57
|
+
|
58
|
+
uart_types = (
|
59
|
+
Type("CH34X", 0x1A86, 0x55D5, "CH34X", 3),
|
60
|
+
Type("CH340", 0x1A86, 0x7523, "CH34X", 1),
|
61
|
+
Type("ESP_JTAG", 0x303A, 0x1001, "CdcAcm", 1, baud_rate_required=False),
|
62
|
+
Type("STM32_VCP", 0x0483, 0x5740, "CdcAcm", 1, baud_rate_required=False),
|
63
|
+
Type("CDC_ACM", 0, 0, "CdcAcm", 1, baud_rate_required=False),
|
64
|
+
Type("CP210X", 0x10C4, 0xEA60, "CP210X", 3),
|
65
|
+
)
|
66
|
+
|
67
|
+
|
68
|
+
def channel_schema(channels, baud_rate_required):
|
69
|
+
return cv.Schema(
|
70
|
+
{
|
71
|
+
cv.Required(CONF_CHANNELS): cv.All(
|
72
|
+
cv.ensure_list(
|
73
|
+
cv.Schema(
|
74
|
+
{
|
75
|
+
cv.GenerateID(): cv.declare_id(USBUartChannel),
|
76
|
+
cv.Optional(CONF_BUFFER_SIZE, default=256): cv.int_range(
|
77
|
+
min=64, max=8192
|
78
|
+
),
|
79
|
+
(
|
80
|
+
cv.Required(CONF_BAUD_RATE)
|
81
|
+
if baud_rate_required
|
82
|
+
else cv.Optional(
|
83
|
+
CONF_BAUD_RATE, default=DEFAULT_BAUD_RATE
|
84
|
+
)
|
85
|
+
): cv.int_range(min=300, max=1000000),
|
86
|
+
cv.Optional(CONF_STOP_BITS, default="1"): cv.enum(
|
87
|
+
UART_STOP_BITS_OPTIONS, upper=True
|
88
|
+
),
|
89
|
+
cv.Optional(CONF_PARITY, default="NONE"): cv.enum(
|
90
|
+
UART_PARITY_OPTIONS, upper=True
|
91
|
+
),
|
92
|
+
cv.Optional(CONF_DATA_BITS, default=8): cv.int_range(
|
93
|
+
min=5, max=8
|
94
|
+
),
|
95
|
+
cv.Optional(CONF_DUMMY_RECEIVER, default=False): cv.boolean,
|
96
|
+
cv.Optional(CONF_DEBUG, default=False): cv.boolean,
|
97
|
+
}
|
98
|
+
)
|
99
|
+
),
|
100
|
+
cv.Length(max=channels),
|
101
|
+
)
|
102
|
+
}
|
103
|
+
)
|
104
|
+
|
105
|
+
|
106
|
+
CONFIG_SCHEMA = cv.ensure_list(
|
107
|
+
cv.typed_schema(
|
108
|
+
{
|
109
|
+
it.name: usb_device_schema(it.cls, it.vid, it.pid).extend(
|
110
|
+
channel_schema(it.max_channels, it.baud_rate_required)
|
111
|
+
)
|
112
|
+
for it in uart_types
|
113
|
+
},
|
114
|
+
upper=True,
|
115
|
+
)
|
116
|
+
)
|
117
|
+
|
118
|
+
|
119
|
+
async def to_code(config):
|
120
|
+
for device in config:
|
121
|
+
var = await register_usb_client(device)
|
122
|
+
for index, channel in enumerate(device[CONF_CHANNELS]):
|
123
|
+
chvar = cg.new_Pvariable(channel[CONF_ID], index, channel[CONF_BUFFER_SIZE])
|
124
|
+
await cg.register_parented(chvar, var)
|
125
|
+
cg.add(chvar.set_rx_buffer_size(channel[CONF_BUFFER_SIZE]))
|
126
|
+
cg.add(chvar.set_stop_bits(channel[CONF_STOP_BITS]))
|
127
|
+
cg.add(chvar.set_data_bits(channel[CONF_DATA_BITS]))
|
128
|
+
cg.add(chvar.set_parity(channel[CONF_PARITY]))
|
129
|
+
cg.add(chvar.set_baud_rate(channel[CONF_BAUD_RATE]))
|
130
|
+
cg.add(chvar.set_dummy_receiver(channel[CONF_DUMMY_RECEIVER]))
|
131
|
+
cg.add(chvar.set_debug(channel[CONF_DEBUG]))
|
132
|
+
cg.add(var.add_channel(chvar))
|
133
|
+
if channel[CONF_DEBUG]:
|
134
|
+
cg.add_define("USE_UART_DEBUGGER")
|
@@ -0,0 +1,80 @@
|
|
1
|
+
#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
|
2
|
+
#include "usb_uart.h"
|
3
|
+
#include "usb/usb_host.h"
|
4
|
+
#include "esphome/core/log.h"
|
5
|
+
|
6
|
+
#include "esphome/components/bytebuffer/bytebuffer.h"
|
7
|
+
|
8
|
+
namespace esphome {
|
9
|
+
namespace usb_uart {
|
10
|
+
|
11
|
+
using namespace bytebuffer;
|
12
|
+
/**
|
13
|
+
* CH34x
|
14
|
+
*/
|
15
|
+
|
16
|
+
void USBUartTypeCH34X::enable_channels() {
|
17
|
+
// enable the channels
|
18
|
+
for (auto channel : this->channels_) {
|
19
|
+
if (!channel->initialised_)
|
20
|
+
continue;
|
21
|
+
usb_host::transfer_cb_t callback = [=](const usb_host::TransferStatus &status) {
|
22
|
+
if (!status.success) {
|
23
|
+
ESP_LOGE(TAG, "Control transfer failed, status=%s", esp_err_to_name(status.error_code));
|
24
|
+
channel->initialised_ = false;
|
25
|
+
}
|
26
|
+
};
|
27
|
+
|
28
|
+
uint8_t divisor = 7;
|
29
|
+
uint32_t clk = 12000000;
|
30
|
+
|
31
|
+
auto baud_rate = channel->baud_rate_;
|
32
|
+
if (baud_rate < 256000) {
|
33
|
+
if (baud_rate > 6000000 / 255) {
|
34
|
+
divisor = 3;
|
35
|
+
clk = 6000000;
|
36
|
+
} else if (baud_rate > 750000 / 255) {
|
37
|
+
divisor = 2;
|
38
|
+
clk = 750000;
|
39
|
+
} else if (baud_rate > 93750 / 255) {
|
40
|
+
divisor = 1;
|
41
|
+
clk = 93750;
|
42
|
+
} else {
|
43
|
+
divisor = 0;
|
44
|
+
clk = 11719;
|
45
|
+
}
|
46
|
+
}
|
47
|
+
ESP_LOGV(TAG, "baud_rate: %" PRIu32 ", divisor: %d, clk: %" PRIu32, baud_rate, divisor, clk);
|
48
|
+
auto factor = static_cast<uint8_t>(clk / baud_rate);
|
49
|
+
if (factor == 0 || factor == 0xFF) {
|
50
|
+
ESP_LOGE(TAG, "Invalid baud rate %" PRIu32, baud_rate);
|
51
|
+
channel->initialised_ = false;
|
52
|
+
continue;
|
53
|
+
}
|
54
|
+
if ((clk / factor - baud_rate) > (baud_rate - clk / (factor + 1)))
|
55
|
+
factor++;
|
56
|
+
factor = 256 - factor;
|
57
|
+
|
58
|
+
uint16_t value = 0xC0;
|
59
|
+
if (channel->stop_bits_ == UART_CONFIG_STOP_BITS_2)
|
60
|
+
value |= 4;
|
61
|
+
switch (channel->parity_) {
|
62
|
+
case UART_CONFIG_PARITY_NONE:
|
63
|
+
break;
|
64
|
+
default:
|
65
|
+
value |= 8 | ((channel->parity_ - 1) << 4);
|
66
|
+
break;
|
67
|
+
}
|
68
|
+
value |= channel->data_bits_ - 5;
|
69
|
+
value <<= 8;
|
70
|
+
value |= 0x8C;
|
71
|
+
uint8_t cmd = 0xA1 + channel->index_;
|
72
|
+
if (channel->index_ >= 2)
|
73
|
+
cmd += 0xE;
|
74
|
+
this->control_transfer(USB_VENDOR_DEV | usb_host::USB_DIR_OUT, cmd, value, (factor << 8) | divisor, callback);
|
75
|
+
}
|
76
|
+
USBUartTypeCdcAcm::enable_channels();
|
77
|
+
}
|
78
|
+
} // namespace usb_uart
|
79
|
+
} // namespace esphome
|
80
|
+
#endif // USE_ESP32_VARIANT_ESP32S2 || USE_ESP32_VARIANT_ESP32S3
|
@@ -0,0 +1,126 @@
|
|
1
|
+
#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
|
2
|
+
#include "usb_uart.h"
|
3
|
+
#include "usb/usb_host.h"
|
4
|
+
#include "esphome/core/log.h"
|
5
|
+
|
6
|
+
#include "esphome/components/bytebuffer/bytebuffer.h"
|
7
|
+
|
8
|
+
namespace esphome {
|
9
|
+
namespace usb_uart {
|
10
|
+
|
11
|
+
using namespace bytebuffer;
|
12
|
+
/**
|
13
|
+
* Silabs CP210x Commands
|
14
|
+
*/
|
15
|
+
|
16
|
+
static constexpr uint8_t IFC_ENABLE = 0x00; // Enable or disable the interface.
|
17
|
+
static constexpr uint8_t SET_BAUDDIV = 0x01; // Set the baud rate divisor.
|
18
|
+
static constexpr uint8_t GET_BAUDDIV = 0x02; // Get the baud rate divisor.
|
19
|
+
static constexpr uint8_t SET_LINE_CTL = 0x03; // Set the line control.
|
20
|
+
static constexpr uint8_t GET_LINE_CTL = 0x04; // Get the line control.
|
21
|
+
static constexpr uint8_t SET_BREAK = 0x05; // Set a BREAK.
|
22
|
+
static constexpr uint8_t IMM_CHAR = 0x06; // Send character out of order.
|
23
|
+
static constexpr uint8_t SET_MHS = 0x07; // Set modem handshaking.
|
24
|
+
static constexpr uint8_t GET_MDMSTS = 0x08; // Get modem status.
|
25
|
+
static constexpr uint8_t SET_XON = 0x09; // Emulate XON.
|
26
|
+
static constexpr uint8_t SET_XOFF = 0x0A; // Emulate XOFF.
|
27
|
+
static constexpr uint8_t SET_EVENTMASK = 0x0B; // Set the event mask.
|
28
|
+
static constexpr uint8_t GET_EVENTMASK = 0x0C; // Get the event mask.
|
29
|
+
static constexpr uint8_t GET_EVENTSTATE = 0x16; // Get the event state.
|
30
|
+
static constexpr uint8_t SET_RECEIVE = 0x17; // Set receiver max timeout.
|
31
|
+
static constexpr uint8_t GET_RECEIVE = 0x18; // Get receiver max timeout.
|
32
|
+
static constexpr uint8_t SET_CHAR = 0x0D; // Set special character individually.
|
33
|
+
static constexpr uint8_t GET_CHARS = 0x0E; // Get special characters.
|
34
|
+
static constexpr uint8_t GET_PROPS = 0x0F; // Get properties.
|
35
|
+
static constexpr uint8_t GET_COMM_STATUS = 0x10; // Get the serial status.
|
36
|
+
static constexpr uint8_t RESET = 0x11; // Reset.
|
37
|
+
static constexpr uint8_t PURGE = 0x12; // Purge.
|
38
|
+
static constexpr uint8_t SET_FLOW = 0x13; // Set flow control.
|
39
|
+
static constexpr uint8_t GET_FLOW = 0x14; // Get flow control.
|
40
|
+
static constexpr uint8_t EMBED_EVENTS = 0x15; // Control embedding of events in the data stream.
|
41
|
+
static constexpr uint8_t GET_BAUDRATE = 0x1D; // Get the baud rate.
|
42
|
+
static constexpr uint8_t SET_BAUDRATE = 0x1E; // Set the baud rate.
|
43
|
+
static constexpr uint8_t SET_CHARS = 0x19; // Set special characters.
|
44
|
+
static constexpr uint8_t VENDOR_SPECIFIC = 0xFF; // Vendor specific command.
|
45
|
+
|
46
|
+
std::vector<CdcEps> USBUartTypeCP210X::parse_descriptors_(usb_device_handle_t dev_hdl) {
|
47
|
+
const usb_config_desc_t *config_desc;
|
48
|
+
const usb_device_desc_t *device_desc;
|
49
|
+
int conf_offset = 0, ep_offset;
|
50
|
+
std::vector<CdcEps> cdc_devs{};
|
51
|
+
|
52
|
+
// Get required descriptors
|
53
|
+
if (usb_host_get_device_descriptor(dev_hdl, &device_desc) != ESP_OK) {
|
54
|
+
ESP_LOGE(TAG, "get_device_descriptor failed");
|
55
|
+
return {};
|
56
|
+
}
|
57
|
+
if (usb_host_get_active_config_descriptor(dev_hdl, &config_desc) != ESP_OK) {
|
58
|
+
ESP_LOGE(TAG, "get_active_config_descriptor failed");
|
59
|
+
return {};
|
60
|
+
}
|
61
|
+
ESP_LOGD(TAG, "bDeviceClass: %u, bDeviceSubClass: %u", device_desc->bDeviceClass, device_desc->bDeviceSubClass);
|
62
|
+
ESP_LOGD(TAG, "bNumInterfaces: %u", config_desc->bNumInterfaces);
|
63
|
+
if (device_desc->bDeviceClass != 0) {
|
64
|
+
ESP_LOGE(TAG, "bDeviceClass != 0");
|
65
|
+
return {};
|
66
|
+
}
|
67
|
+
|
68
|
+
for (uint8_t i = 0; i != config_desc->bNumInterfaces; i++) {
|
69
|
+
auto data_desc = usb_parse_interface_descriptor(config_desc, 0, 0, &conf_offset);
|
70
|
+
if (!data_desc) {
|
71
|
+
ESP_LOGE(TAG, "data_desc: usb_parse_interface_descriptor failed");
|
72
|
+
break;
|
73
|
+
}
|
74
|
+
if (data_desc->bNumEndpoints != 2 || data_desc->bInterfaceClass != USB_CLASS_VENDOR_SPEC) {
|
75
|
+
ESP_LOGE(TAG, "data_desc: bInterfaceClass == %u, bInterfaceSubClass == %u, bNumEndpoints == %u",
|
76
|
+
data_desc->bInterfaceClass, data_desc->bInterfaceSubClass, data_desc->bNumEndpoints);
|
77
|
+
continue;
|
78
|
+
}
|
79
|
+
ep_offset = conf_offset;
|
80
|
+
auto out_ep = usb_parse_endpoint_descriptor_by_index(data_desc, 0, config_desc->wTotalLength, &ep_offset);
|
81
|
+
if (!out_ep) {
|
82
|
+
ESP_LOGE(TAG, "out_ep: usb_parse_endpoint_descriptor_by_index failed");
|
83
|
+
continue;
|
84
|
+
}
|
85
|
+
ep_offset = conf_offset;
|
86
|
+
auto in_ep = usb_parse_endpoint_descriptor_by_index(data_desc, 1, config_desc->wTotalLength, &ep_offset);
|
87
|
+
if (!in_ep) {
|
88
|
+
ESP_LOGE(TAG, "in_ep: usb_parse_endpoint_descriptor_by_index failed");
|
89
|
+
continue;
|
90
|
+
}
|
91
|
+
if (in_ep->bEndpointAddress & usb_host::USB_DIR_IN) {
|
92
|
+
cdc_devs.push_back({CdcEps{nullptr, in_ep, out_ep, data_desc->bInterfaceNumber}});
|
93
|
+
} else {
|
94
|
+
cdc_devs.push_back({CdcEps{nullptr, out_ep, in_ep, data_desc->bInterfaceNumber}});
|
95
|
+
}
|
96
|
+
}
|
97
|
+
return cdc_devs;
|
98
|
+
}
|
99
|
+
|
100
|
+
void USBUartTypeCP210X::enable_channels() {
|
101
|
+
// enable the channels
|
102
|
+
for (auto channel : this->channels_) {
|
103
|
+
if (!channel->initialised_)
|
104
|
+
continue;
|
105
|
+
usb_host::transfer_cb_t callback = [=](const usb_host::TransferStatus &status) {
|
106
|
+
if (!status.success) {
|
107
|
+
ESP_LOGE(TAG, "Control transfer failed, status=%s", esp_err_to_name(status.error_code));
|
108
|
+
channel->initialised_ = false;
|
109
|
+
}
|
110
|
+
};
|
111
|
+
this->control_transfer(USB_VENDOR_IFC | usb_host::USB_DIR_OUT, IFC_ENABLE, 1, channel->index_, callback);
|
112
|
+
uint16_t line_control = channel->stop_bits_;
|
113
|
+
line_control |= static_cast<uint8_t>(channel->parity_) << 4;
|
114
|
+
line_control |= channel->data_bits_ << 8;
|
115
|
+
ESP_LOGD(TAG, "Line control value 0x%X", line_control);
|
116
|
+
this->control_transfer(USB_VENDOR_IFC | usb_host::USB_DIR_OUT, SET_LINE_CTL, line_control, channel->index_,
|
117
|
+
callback);
|
118
|
+
auto baud = ByteBuffer::wrap(channel->baud_rate_, LITTLE);
|
119
|
+
this->control_transfer(USB_VENDOR_IFC | usb_host::USB_DIR_OUT, SET_BAUDRATE, 0, channel->index_, callback,
|
120
|
+
baud.get_data());
|
121
|
+
}
|
122
|
+
USBUartTypeCdcAcm::enable_channels();
|
123
|
+
}
|
124
|
+
} // namespace usb_uart
|
125
|
+
} // namespace esphome
|
126
|
+
#endif // USE_ESP32_VARIANT_ESP32S2 || USE_ESP32_VARIANT_ESP32S3
|
@@ -0,0 +1,328 @@
|
|
1
|
+
// Should not be needed, but it's required to pass CI clang-tidy checks
|
2
|
+
#if defined(USE_ESP32_VARIANT_ESP32S2) || defined(USE_ESP32_VARIANT_ESP32S3)
|
3
|
+
#include "usb_uart.h"
|
4
|
+
#include "esphome/core/log.h"
|
5
|
+
#include "esphome/components/uart/uart_debugger.h"
|
6
|
+
|
7
|
+
#include <cinttypes>
|
8
|
+
|
9
|
+
namespace esphome {
|
10
|
+
namespace usb_uart {
|
11
|
+
|
12
|
+
/**
|
13
|
+
*
|
14
|
+
* Given a configuration, look for the required interfaces defining a CDC-ACM device
|
15
|
+
* @param config_desc The configuration descriptor
|
16
|
+
* @param intf_idx The index of the interface to be examined
|
17
|
+
* @return
|
18
|
+
*/
|
19
|
+
static optional<CdcEps> get_cdc(const usb_config_desc_t *config_desc, uint8_t intf_idx) {
|
20
|
+
int conf_offset, ep_offset;
|
21
|
+
const usb_ep_desc_t *notify_ep{}, *in_ep{}, *out_ep{};
|
22
|
+
uint8_t interface_number = 0;
|
23
|
+
// look for an interface with one interrupt endpoint (notify), and an interface with two bulk endpoints (data in/out)
|
24
|
+
for (;;) {
|
25
|
+
auto intf_desc = usb_parse_interface_descriptor(config_desc, intf_idx++, 0, &conf_offset);
|
26
|
+
if (!intf_desc) {
|
27
|
+
ESP_LOGE(TAG, "usb_parse_interface_descriptor failed");
|
28
|
+
return nullopt;
|
29
|
+
}
|
30
|
+
if (intf_desc->bNumEndpoints == 1) {
|
31
|
+
ep_offset = conf_offset;
|
32
|
+
notify_ep = usb_parse_endpoint_descriptor_by_index(intf_desc, 0, config_desc->wTotalLength, &ep_offset);
|
33
|
+
if (!notify_ep) {
|
34
|
+
ESP_LOGE(TAG, "notify_ep: usb_parse_endpoint_descriptor_by_index failed");
|
35
|
+
return nullopt;
|
36
|
+
}
|
37
|
+
if (notify_ep->bmAttributes != USB_BM_ATTRIBUTES_XFER_INT)
|
38
|
+
notify_ep = nullptr;
|
39
|
+
} else if (USB_CLASS_CDC_DATA && intf_desc->bNumEndpoints == 2) {
|
40
|
+
interface_number = intf_desc->bInterfaceNumber;
|
41
|
+
ep_offset = conf_offset;
|
42
|
+
out_ep = usb_parse_endpoint_descriptor_by_index(intf_desc, 0, config_desc->wTotalLength, &ep_offset);
|
43
|
+
if (!out_ep) {
|
44
|
+
ESP_LOGE(TAG, "out_ep: usb_parse_endpoint_descriptor_by_index failed");
|
45
|
+
return nullopt;
|
46
|
+
}
|
47
|
+
if (out_ep->bmAttributes != USB_BM_ATTRIBUTES_XFER_BULK)
|
48
|
+
out_ep = nullptr;
|
49
|
+
ep_offset = conf_offset;
|
50
|
+
in_ep = usb_parse_endpoint_descriptor_by_index(intf_desc, 1, config_desc->wTotalLength, &ep_offset);
|
51
|
+
if (!in_ep) {
|
52
|
+
ESP_LOGE(TAG, "in_ep: usb_parse_endpoint_descriptor_by_index failed");
|
53
|
+
return nullopt;
|
54
|
+
}
|
55
|
+
if (in_ep->bmAttributes != USB_BM_ATTRIBUTES_XFER_BULK)
|
56
|
+
in_ep = nullptr;
|
57
|
+
}
|
58
|
+
if (in_ep != nullptr && out_ep != nullptr && notify_ep != nullptr)
|
59
|
+
break;
|
60
|
+
}
|
61
|
+
if (in_ep->bEndpointAddress & usb_host::USB_DIR_IN)
|
62
|
+
return CdcEps{notify_ep, in_ep, out_ep, interface_number};
|
63
|
+
return CdcEps{notify_ep, out_ep, in_ep, interface_number};
|
64
|
+
}
|
65
|
+
|
66
|
+
std::vector<CdcEps> USBUartTypeCdcAcm::parse_descriptors_(usb_device_handle_t dev_hdl) {
|
67
|
+
const usb_config_desc_t *config_desc;
|
68
|
+
const usb_device_desc_t *device_desc;
|
69
|
+
int desc_offset = 0;
|
70
|
+
std::vector<CdcEps> cdc_devs{};
|
71
|
+
|
72
|
+
// Get required descriptors
|
73
|
+
if (usb_host_get_device_descriptor(dev_hdl, &device_desc) != ESP_OK) {
|
74
|
+
ESP_LOGE(TAG, "get_device_descriptor failed");
|
75
|
+
return {};
|
76
|
+
}
|
77
|
+
if (usb_host_get_active_config_descriptor(dev_hdl, &config_desc) != ESP_OK) {
|
78
|
+
ESP_LOGE(TAG, "get_active_config_descriptor failed");
|
79
|
+
return {};
|
80
|
+
}
|
81
|
+
if (device_desc->bDeviceClass == USB_CLASS_COMM) {
|
82
|
+
// single CDC-ACM device
|
83
|
+
if (auto eps = get_cdc(config_desc, 0)) {
|
84
|
+
ESP_LOGV(TAG, "Found CDC-ACM device");
|
85
|
+
cdc_devs.push_back(*eps);
|
86
|
+
}
|
87
|
+
return cdc_devs;
|
88
|
+
}
|
89
|
+
if (((device_desc->bDeviceClass == USB_CLASS_MISC) && (device_desc->bDeviceSubClass == USB_SUBCLASS_COMMON) &&
|
90
|
+
(device_desc->bDeviceProtocol == USB_DEVICE_PROTOCOL_IAD)) ||
|
91
|
+
((device_desc->bDeviceClass == USB_CLASS_PER_INTERFACE) && (device_desc->bDeviceSubClass == USB_SUBCLASS_NULL) &&
|
92
|
+
(device_desc->bDeviceProtocol == USB_PROTOCOL_NULL))) {
|
93
|
+
// This is a composite device, that uses Interface Association Descriptor
|
94
|
+
const auto *this_desc = reinterpret_cast<const usb_standard_desc_t *>(config_desc);
|
95
|
+
for (;;) {
|
96
|
+
this_desc = usb_parse_next_descriptor_of_type(this_desc, config_desc->wTotalLength,
|
97
|
+
USB_B_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, &desc_offset);
|
98
|
+
if (!this_desc)
|
99
|
+
break;
|
100
|
+
const auto *iad_desc = reinterpret_cast<const usb_iad_desc_t *>(this_desc);
|
101
|
+
|
102
|
+
if (iad_desc->bFunctionClass == USB_CLASS_COMM && iad_desc->bFunctionSubClass == USB_CDC_SUBCLASS_ACM) {
|
103
|
+
ESP_LOGV(TAG, "Found CDC-ACM device in composite device");
|
104
|
+
if (auto eps = get_cdc(config_desc, iad_desc->bFirstInterface))
|
105
|
+
cdc_devs.push_back(*eps);
|
106
|
+
}
|
107
|
+
}
|
108
|
+
}
|
109
|
+
return cdc_devs;
|
110
|
+
}
|
111
|
+
|
112
|
+
void RingBuffer::push(uint8_t item) {
|
113
|
+
this->buffer_[this->insert_pos_] = item;
|
114
|
+
this->insert_pos_ = (this->insert_pos_ + 1) % this->buffer_size_;
|
115
|
+
}
|
116
|
+
void RingBuffer::push(const uint8_t *data, size_t len) {
|
117
|
+
for (size_t i = 0; i != len; i++) {
|
118
|
+
this->buffer_[this->insert_pos_] = *data++;
|
119
|
+
this->insert_pos_ = (this->insert_pos_ + 1) % this->buffer_size_;
|
120
|
+
}
|
121
|
+
}
|
122
|
+
|
123
|
+
uint8_t RingBuffer::pop() {
|
124
|
+
uint8_t item = this->buffer_[this->read_pos_];
|
125
|
+
this->read_pos_ = (this->read_pos_ + 1) % this->buffer_size_;
|
126
|
+
return item;
|
127
|
+
}
|
128
|
+
size_t RingBuffer::pop(uint8_t *data, size_t len) {
|
129
|
+
len = std::min(len, this->get_available());
|
130
|
+
for (size_t i = 0; i != len; i++) {
|
131
|
+
*data++ = this->buffer_[this->read_pos_];
|
132
|
+
this->read_pos_ = (this->read_pos_ + 1) % this->buffer_size_;
|
133
|
+
}
|
134
|
+
return len;
|
135
|
+
}
|
136
|
+
void USBUartChannel::write_array(const uint8_t *data, size_t len) {
|
137
|
+
if (!this->initialised_) {
|
138
|
+
ESP_LOGV(TAG, "Channel not initialised - write ignored");
|
139
|
+
return;
|
140
|
+
}
|
141
|
+
while (this->output_buffer_.get_free_space() != 0 && len-- != 0) {
|
142
|
+
this->output_buffer_.push(*data++);
|
143
|
+
}
|
144
|
+
len++;
|
145
|
+
if (len > 0) {
|
146
|
+
ESP_LOGE(TAG, "Buffer full - failed to write %d bytes", len);
|
147
|
+
}
|
148
|
+
this->parent_->start_output(this);
|
149
|
+
}
|
150
|
+
|
151
|
+
bool USBUartChannel::peek_byte(uint8_t *data) {
|
152
|
+
if (this->input_buffer_.is_empty()) {
|
153
|
+
return false;
|
154
|
+
}
|
155
|
+
*data = this->input_buffer_.peek();
|
156
|
+
return true;
|
157
|
+
}
|
158
|
+
bool USBUartChannel::read_array(uint8_t *data, size_t len) {
|
159
|
+
if (!this->initialised_) {
|
160
|
+
ESP_LOGV(TAG, "Channel not initialised - read ignored");
|
161
|
+
return false;
|
162
|
+
}
|
163
|
+
auto available = this->available();
|
164
|
+
bool status = true;
|
165
|
+
if (len > available) {
|
166
|
+
ESP_LOGV(TAG, "underflow: requested %zu but returned %d, bytes", len, available);
|
167
|
+
len = available;
|
168
|
+
status = false;
|
169
|
+
}
|
170
|
+
for (size_t i = 0; i != len; i++) {
|
171
|
+
*data++ = this->input_buffer_.pop();
|
172
|
+
}
|
173
|
+
this->parent_->start_input(this);
|
174
|
+
return status;
|
175
|
+
}
|
176
|
+
void USBUartComponent::setup() { USBClient::setup(); }
|
177
|
+
void USBUartComponent::loop() { USBClient::loop(); }
|
178
|
+
void USBUartComponent::dump_config() {
|
179
|
+
USBClient::dump_config();
|
180
|
+
for (auto &channel : this->channels_) {
|
181
|
+
ESP_LOGCONFIG(TAG,
|
182
|
+
" UART Channel %d\n"
|
183
|
+
" Baud Rate: %" PRIu32 " baud\n"
|
184
|
+
" Data Bits: %u\n"
|
185
|
+
" Parity: %s\n"
|
186
|
+
" Stop bits: %s\n"
|
187
|
+
" Debug: %s\n"
|
188
|
+
" Dummy receiver: %s",
|
189
|
+
channel->index_, channel->baud_rate_, channel->data_bits_, PARITY_NAMES[channel->parity_],
|
190
|
+
STOP_BITS_NAMES[channel->stop_bits_], YESNO(channel->debug_), YESNO(channel->dummy_receiver_));
|
191
|
+
}
|
192
|
+
}
|
193
|
+
void USBUartComponent::start_input(USBUartChannel *channel) {
|
194
|
+
if (!channel->initialised_ || channel->input_started_ ||
|
195
|
+
channel->input_buffer_.get_free_space() < channel->cdc_dev_.in_ep->wMaxPacketSize)
|
196
|
+
return;
|
197
|
+
auto ep = channel->cdc_dev_.in_ep;
|
198
|
+
auto callback = [this, channel](const usb_host::TransferStatus &status) {
|
199
|
+
ESP_LOGV(TAG, "Transfer result: length: %u; status %X", status.data_len, status.error_code);
|
200
|
+
if (!status.success) {
|
201
|
+
ESP_LOGE(TAG, "Control transfer failed, status=%s", esp_err_to_name(status.error_code));
|
202
|
+
return;
|
203
|
+
}
|
204
|
+
#ifdef USE_UART_DEBUGGER
|
205
|
+
if (channel->debug_) {
|
206
|
+
uart::UARTDebug::log_hex(uart::UART_DIRECTION_RX,
|
207
|
+
std::vector<uint8_t>(status.data, status.data + status.data_len), ','); // NOLINT()
|
208
|
+
}
|
209
|
+
#endif
|
210
|
+
channel->input_started_ = false;
|
211
|
+
if (!channel->dummy_receiver_) {
|
212
|
+
for (size_t i = 0; i != status.data_len; i++) {
|
213
|
+
channel->input_buffer_.push(status.data[i]);
|
214
|
+
}
|
215
|
+
}
|
216
|
+
if (channel->input_buffer_.get_free_space() >= channel->cdc_dev_.in_ep->wMaxPacketSize) {
|
217
|
+
this->defer([this, channel] { this->start_input(channel); });
|
218
|
+
}
|
219
|
+
};
|
220
|
+
channel->input_started_ = true;
|
221
|
+
this->transfer_in(ep->bEndpointAddress, callback, ep->wMaxPacketSize);
|
222
|
+
}
|
223
|
+
|
224
|
+
void USBUartComponent::start_output(USBUartChannel *channel) {
|
225
|
+
if (channel->output_started_)
|
226
|
+
return;
|
227
|
+
if (channel->output_buffer_.is_empty()) {
|
228
|
+
return;
|
229
|
+
}
|
230
|
+
auto ep = channel->cdc_dev_.out_ep;
|
231
|
+
auto callback = [this, channel](const usb_host::TransferStatus &status) {
|
232
|
+
ESP_LOGV(TAG, "Output Transfer result: length: %u; status %X", status.data_len, status.error_code);
|
233
|
+
channel->output_started_ = false;
|
234
|
+
this->defer([this, channel] { this->start_output(channel); });
|
235
|
+
};
|
236
|
+
channel->output_started_ = true;
|
237
|
+
uint8_t data[ep->wMaxPacketSize];
|
238
|
+
auto len = channel->output_buffer_.pop(data, ep->wMaxPacketSize);
|
239
|
+
this->transfer_out(ep->bEndpointAddress, callback, data, len);
|
240
|
+
#ifdef USE_UART_DEBUGGER
|
241
|
+
if (channel->debug_) {
|
242
|
+
uart::UARTDebug::log_hex(uart::UART_DIRECTION_TX, std::vector<uint8_t>(data, data + len), ','); // NOLINT()
|
243
|
+
}
|
244
|
+
#endif
|
245
|
+
ESP_LOGV(TAG, "Output %d bytes started", len);
|
246
|
+
}
|
247
|
+
|
248
|
+
/**
|
249
|
+
* Hacky fix for some devices that report incorrect MPS values
|
250
|
+
* @param ep The endpoint descriptor
|
251
|
+
*/
|
252
|
+
static void fix_mps(const usb_ep_desc_t *ep) {
|
253
|
+
if (ep != nullptr) {
|
254
|
+
auto *ep_mutable = const_cast<usb_ep_desc_t *>(ep);
|
255
|
+
if (ep->wMaxPacketSize > 64) {
|
256
|
+
ESP_LOGW(TAG, "Corrected MPS of EP %u from %u to 64", ep->bEndpointAddress, ep->wMaxPacketSize);
|
257
|
+
ep_mutable->wMaxPacketSize = 64;
|
258
|
+
}
|
259
|
+
}
|
260
|
+
}
|
261
|
+
void USBUartTypeCdcAcm::on_connected() {
|
262
|
+
auto cdc_devs = this->parse_descriptors_(this->device_handle_);
|
263
|
+
if (cdc_devs.empty()) {
|
264
|
+
this->status_set_error("No CDC-ACM device found");
|
265
|
+
this->disconnect();
|
266
|
+
return;
|
267
|
+
}
|
268
|
+
ESP_LOGD(TAG, "Found %zu CDC-ACM devices", cdc_devs.size());
|
269
|
+
auto i = 0;
|
270
|
+
for (auto channel : this->channels_) {
|
271
|
+
if (i == cdc_devs.size()) {
|
272
|
+
ESP_LOGE(TAG, "No configuration found for channel %d", channel->index_);
|
273
|
+
this->status_set_warning("No configuration found for channel");
|
274
|
+
break;
|
275
|
+
}
|
276
|
+
channel->cdc_dev_ = cdc_devs[i++];
|
277
|
+
fix_mps(channel->cdc_dev_.in_ep);
|
278
|
+
fix_mps(channel->cdc_dev_.out_ep);
|
279
|
+
channel->initialised_ = true;
|
280
|
+
auto err = usb_host_interface_claim(this->handle_, this->device_handle_, channel->cdc_dev_.interface_number, 0);
|
281
|
+
if (err != ESP_OK) {
|
282
|
+
ESP_LOGE(TAG, "usb_host_interface_claim failed: %s, channel=%d, intf=%d", esp_err_to_name(err), channel->index_,
|
283
|
+
channel->cdc_dev_.interface_number);
|
284
|
+
this->status_set_error("usb_host_interface_claim failed");
|
285
|
+
this->disconnect();
|
286
|
+
return;
|
287
|
+
}
|
288
|
+
}
|
289
|
+
this->enable_channels();
|
290
|
+
}
|
291
|
+
|
292
|
+
void USBUartTypeCdcAcm::on_disconnected() {
|
293
|
+
for (auto channel : this->channels_) {
|
294
|
+
if (channel->cdc_dev_.in_ep != nullptr) {
|
295
|
+
usb_host_endpoint_halt(this->device_handle_, channel->cdc_dev_.in_ep->bEndpointAddress);
|
296
|
+
usb_host_endpoint_flush(this->device_handle_, channel->cdc_dev_.in_ep->bEndpointAddress);
|
297
|
+
}
|
298
|
+
if (channel->cdc_dev_.out_ep != nullptr) {
|
299
|
+
usb_host_endpoint_halt(this->device_handle_, channel->cdc_dev_.out_ep->bEndpointAddress);
|
300
|
+
usb_host_endpoint_flush(this->device_handle_, channel->cdc_dev_.out_ep->bEndpointAddress);
|
301
|
+
}
|
302
|
+
if (channel->cdc_dev_.notify_ep != nullptr) {
|
303
|
+
usb_host_endpoint_halt(this->device_handle_, channel->cdc_dev_.notify_ep->bEndpointAddress);
|
304
|
+
usb_host_endpoint_flush(this->device_handle_, channel->cdc_dev_.notify_ep->bEndpointAddress);
|
305
|
+
}
|
306
|
+
usb_host_interface_release(this->handle_, this->device_handle_, channel->cdc_dev_.interface_number);
|
307
|
+
channel->initialised_ = false;
|
308
|
+
channel->input_started_ = false;
|
309
|
+
channel->output_started_ = false;
|
310
|
+
channel->input_buffer_.clear();
|
311
|
+
channel->output_buffer_.clear();
|
312
|
+
}
|
313
|
+
USBClient::on_disconnected();
|
314
|
+
}
|
315
|
+
|
316
|
+
void USBUartTypeCdcAcm::enable_channels() {
|
317
|
+
for (auto channel : this->channels_) {
|
318
|
+
if (!channel->initialised_)
|
319
|
+
continue;
|
320
|
+
channel->input_started_ = false;
|
321
|
+
channel->output_started_ = false;
|
322
|
+
this->start_input(channel);
|
323
|
+
}
|
324
|
+
}
|
325
|
+
|
326
|
+
} // namespace usb_uart
|
327
|
+
} // namespace esphome
|
328
|
+
#endif // USE_ESP32_VARIANT_ESP32S2 || USE_ESP32_VARIANT_ESP32S3
|