esphome 2025.7.5__py3-none-any.whl → 2025.8.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 +189 -82
- esphome/automation.py +2 -4
- esphome/build_gen/__init__.py +0 -0
- esphome/build_gen/platformio.py +102 -0
- esphome/components/a4988/a4988.cpp +0 -1
- esphome/components/absolute_humidity/absolute_humidity.cpp +0 -2
- esphome/components/absolute_humidity/sensor.py +2 -2
- esphome/components/adc/__init__.py +123 -85
- esphome/components/adc/adc_sensor.h +98 -35
- esphome/components/adc/adc_sensor_common.cpp +10 -4
- esphome/components/adc/adc_sensor_esp32.cpp +291 -123
- esphome/components/adc/adc_sensor_esp8266.cpp +1 -4
- esphome/components/adc/adc_sensor_libretiny.cpp +1 -2
- esphome/components/adc/adc_sensor_rp2040.cpp +1 -2
- esphome/components/adc/adc_sensor_zephyr.cpp +207 -0
- esphome/components/adc/sensor.py +61 -27
- esphome/components/adc128s102/adc128s102.cpp +1 -4
- esphome/components/ade7880/sensor.py +75 -49
- esphome/components/ads1115/ads1115.cpp +0 -1
- esphome/components/ads1118/ads1118.cpp +0 -1
- esphome/components/ags10/ags10.cpp +0 -4
- esphome/components/aht10/aht10.cpp +0 -4
- esphome/components/aic3204/aic3204.cpp +0 -2
- esphome/components/airthings_wave_plus/__init__.py +1 -1
- esphome/components/airthings_wave_plus/airthings_wave_plus.cpp +22 -4
- esphome/components/airthings_wave_plus/airthings_wave_plus.h +10 -1
- esphome/components/airthings_wave_plus/sensor.py +55 -28
- esphome/components/alarm_control_panel/__init__.py +4 -9
- esphome/components/am2315c/am2315c.cpp +0 -2
- esphome/components/am2320/am2320.cpp +0 -1
- esphome/components/animation/__init__.py +14 -11
- esphome/components/apds9306/apds9306.cpp +0 -4
- esphome/components/apds9960/apds9960.cpp +0 -1
- esphome/components/api/__init__.py +29 -4
- esphome/components/api/api_connection.cpp +378 -401
- esphome/components/api/api_connection.h +102 -52
- esphome/components/api/api_frame_helper.cpp +69 -896
- esphome/components/api/api_frame_helper.h +31 -126
- esphome/components/api/api_frame_helper_noise.cpp +583 -0
- esphome/components/api/api_frame_helper_noise.h +68 -0
- esphome/components/api/api_frame_helper_plaintext.cpp +290 -0
- esphome/components/api/api_frame_helper_plaintext.h +53 -0
- esphome/components/api/api_noise_context.h +2 -4
- esphome/components/api/api_pb2.cpp +1601 -1808
- esphome/components/api/api_pb2.h +367 -323
- esphome/components/api/api_pb2_dump.cpp +1137 -3466
- esphome/components/api/api_pb2_includes.h +34 -0
- esphome/components/api/api_pb2_service.cpp +94 -105
- esphome/components/api/api_pb2_service.h +27 -16
- esphome/components/api/api_server.cpp +18 -17
- esphome/components/api/api_server.h +8 -5
- esphome/components/api/client.py +16 -8
- esphome/components/api/custom_api_device.h +68 -14
- esphome/components/api/homeassistant_service.h +24 -19
- esphome/components/api/list_entities.cpp +3 -5
- esphome/components/api/list_entities.h +2 -4
- esphome/components/api/proto.cpp +3 -5
- esphome/components/api/proto.h +239 -274
- esphome/components/api/subscribe_state.cpp +2 -4
- esphome/components/api/subscribe_state.h +2 -4
- esphome/components/api/user_services.cpp +2 -4
- esphome/components/api/user_services.h +8 -8
- esphome/components/as3935/as3935.cpp +0 -2
- esphome/components/as3935_spi/as3935_spi.cpp +0 -2
- esphome/components/as5600/__init__.py +1 -1
- esphome/components/as5600/as5600.cpp +0 -2
- esphome/components/as5600/sensor/__init__.py +0 -1
- esphome/components/as7341/as7341.cpp +0 -1
- esphome/components/async_tcp/__init__.py +1 -1
- esphome/components/at581x/at581x.cpp +1 -1
- esphome/components/atm90e26/atm90e26.cpp +0 -1
- esphome/components/atm90e32/atm90e32.cpp +488 -118
- esphome/components/atm90e32/atm90e32.h +44 -5
- esphome/components/audio/audio.h +2 -2
- esphome/components/axs15231/touchscreen/axs15231_touchscreen.cpp +0 -2
- esphome/components/beken_spi_led_strip/led_strip.cpp +0 -2
- esphome/components/bh1750/bh1750.cpp +0 -1
- esphome/components/binary_sensor/__init__.py +14 -12
- esphome/components/ble_client/__init__.py +4 -7
- esphome/components/bluetooth_proxy/__init__.py +40 -3
- esphome/components/bluetooth_proxy/bluetooth_connection.cpp +387 -82
- esphome/components/bluetooth_proxy/bluetooth_connection.h +16 -5
- esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +102 -311
- esphome/components/bluetooth_proxy/bluetooth_proxy.h +30 -14
- esphome/components/bme280_base/bme280_base.cpp +15 -16
- esphome/components/bme680/bme680.cpp +2 -3
- esphome/components/bme680_bsec/bme680_bsec.cpp +0 -2
- esphome/components/bme68x_bsec2/bme68x_bsec2.cpp +0 -2
- esphome/components/bmi160/bmi160.cpp +0 -1
- esphome/components/bmp085/bmp085.cpp +0 -1
- esphome/components/bmp280_base/bmp280_base.cpp +13 -14
- esphome/components/bmp3xx_base/bmp3xx_base.cpp +0 -1
- esphome/components/bmp581/bmp581.cpp +0 -2
- esphome/components/bp1658cj/bp1658cj.cpp +0 -1
- esphome/components/bp5758d/bp5758d.cpp +0 -1
- esphome/components/button/__init__.py +0 -1
- esphome/components/canbus/__init__.py +2 -3
- esphome/components/canbus/canbus.cpp +0 -1
- esphome/components/cap1188/cap1188.cpp +0 -2
- esphome/components/captive_portal/__init__.py +1 -1
- esphome/components/cd74hc4067/cd74hc4067.cpp +0 -2
- esphome/components/ch422g/ch422g.cpp +0 -1
- esphome/components/chsc6x/chsc6x_touchscreen.cpp +0 -3
- esphome/components/climate/__init__.py +0 -1
- esphome/components/climate/climate_traits.h +24 -0
- esphome/components/cm1106/cm1106.cpp +0 -1
- esphome/components/const/__init__.py +6 -0
- esphome/components/cover/__init__.py +0 -1
- esphome/components/cover/cover.cpp +9 -13
- esphome/components/cs5460a/cs5460a.cpp +0 -2
- esphome/components/cse7761/cse7761.cpp +0 -1
- esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +0 -2
- esphome/components/cst816/touchscreen/cst816_touchscreen.cpp +0 -2
- esphome/components/dac7678/dac7678_output.cpp +0 -2
- esphome/components/dallas_temp/dallas_temp.cpp +0 -1
- esphome/components/datetime/__init__.py +0 -2
- esphome/components/debug/__init__.py +15 -1
- esphome/components/debug/debug_zephyr.cpp +281 -0
- esphome/components/debug/sensor.py +2 -1
- esphome/components/deep_sleep/deep_sleep_component.cpp +0 -1
- esphome/components/deep_sleep/deep_sleep_esp32.cpp +20 -1
- esphome/components/dfrobot_sen0395/__init__.py +1 -2
- esphome/components/dht/dht.cpp +0 -1
- esphome/components/dht12/dht12.cpp +0 -1
- esphome/components/display/__init__.py +16 -3
- esphome/components/display_menu_base/__init__.py +1 -1
- esphome/components/dps310/dps310.cpp +0 -2
- esphome/components/ds1307/ds1307.cpp +0 -1
- esphome/components/ds2484/ds2484.cpp +0 -1
- esphome/components/duty_cycle/duty_cycle_sensor.cpp +0 -1
- esphome/components/ee895/ee895.cpp +0 -1
- esphome/components/ektf2232/touchscreen/ektf2232.cpp +0 -1
- esphome/components/emc2101/emc2101.cpp +0 -2
- esphome/components/ens160_base/ens160_base.cpp +0 -2
- esphome/components/ens210/ens210.cpp +0 -1
- esphome/components/es7210/es7210.cpp +0 -2
- esphome/components/es7243e/es7243e.cpp +0 -2
- esphome/components/es8156/es8156.cpp +0 -2
- esphome/components/es8311/es8311.cpp +0 -2
- esphome/components/es8388/es8388.cpp +0 -2
- esphome/components/esp32/__init__.py +199 -58
- esphome/components/esp32/boards.py +17 -0
- esphome/components/esp32/gpio.cpp +0 -1
- esphome/components/esp32/gpio.py +1 -2
- esphome/components/esp32/gpio_esp32_h2.py +2 -7
- esphome/components/esp32/gpio_esp32_p4.py +2 -7
- esphome/components/esp32/post_build.py.script +112 -61
- esphome/components/esp32_ble/__init__.py +40 -2
- esphome/components/esp32_ble/ble.cpp +12 -8
- esphome/components/esp32_ble/ble.h +18 -18
- esphome/components/esp32_ble/ble_advertising.cpp +5 -5
- esphome/components/esp32_ble/ble_advertising.h +7 -5
- esphome/components/esp32_ble/ble_event.h +2 -4
- esphome/components/esp32_ble/ble_scan_result.h +2 -4
- esphome/components/esp32_ble/ble_uuid.cpp +5 -5
- esphome/components/esp32_ble/ble_uuid.h +6 -5
- esphome/components/esp32_ble_beacon/__init__.py +4 -0
- esphome/components/esp32_ble_client/__init__.py +1 -1
- esphome/components/esp32_ble_client/ble_characteristic.cpp +4 -4
- esphome/components/esp32_ble_client/ble_characteristic.h +6 -4
- esphome/components/esp32_ble_client/ble_client_base.cpp +155 -104
- esphome/components/esp32_ble_client/ble_client_base.h +17 -6
- esphome/components/esp32_ble_client/ble_descriptor.h +6 -4
- esphome/components/esp32_ble_client/ble_service.cpp +4 -4
- esphome/components/esp32_ble_client/ble_service.h +6 -4
- esphome/components/esp32_ble_server/__init__.py +15 -12
- esphome/components/esp32_ble_tracker/__init__.py +79 -11
- esphome/components/esp32_ble_tracker/automation.h +4 -4
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +264 -261
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +103 -37
- esphome/components/esp32_camera/__init__.py +13 -1
- esphome/components/esp32_camera/esp32_camera.cpp +7 -2
- esphome/components/esp32_camera/esp32_camera.h +1 -0
- esphome/components/esp32_dac/esp32_dac.cpp +3 -19
- esphome/components/esp32_dac/esp32_dac.h +4 -8
- esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -6
- esphome/components/esp32_rmt_led_strip/light.py +1 -1
- esphome/components/esp32_touch/__init__.py +2 -3
- esphome/components/esp32_touch/esp32_touch.h +9 -6
- esphome/components/esp32_touch/esp32_touch_common.cpp +2 -0
- esphome/components/esp32_touch/esp32_touch_v1.cpp +7 -9
- esphome/components/esp32_touch/esp32_touch_v2.cpp +10 -6
- esphome/components/esp8266/__init__.py +3 -1
- esphome/components/esp8266_pwm/esp8266_pwm.cpp +0 -1
- esphome/components/esphome/ota/__init__.py +1 -2
- esphome/components/esphome/ota/ota_esphome.cpp +150 -77
- esphome/components/esphome/ota/ota_esphome.h +8 -1
- esphome/components/espnow/__init__.py +309 -0
- esphome/components/espnow/automation.h +175 -0
- esphome/components/espnow/espnow_component.cpp +468 -0
- esphome/components/espnow/espnow_component.h +183 -0
- esphome/components/espnow/espnow_err.h +19 -0
- esphome/components/espnow/espnow_packet.h +166 -0
- esphome/components/ethernet/__init__.py +7 -1
- esphome/components/ethernet/esp_eth_phy_jl1101.c +5 -0
- esphome/components/ethernet/ethernet_component.cpp +0 -1
- esphome/components/ethernet/ethernet_component.h +4 -0
- esphome/components/ethernet_info/ethernet_info_text_sensor.h +0 -3
- esphome/components/event/__init__.py +0 -1
- esphome/components/factory_reset/__init__.py +92 -0
- esphome/components/factory_reset/factory_reset.cpp +76 -0
- esphome/components/factory_reset/factory_reset.h +43 -0
- esphome/components/fan/__init__.py +0 -1
- esphome/components/fan/fan_traits.h +16 -0
- esphome/components/fastled_base/fastled_light.cpp +0 -1
- esphome/components/fastled_spi/light.py +1 -3
- esphome/components/fingerprint_grow/fingerprint_grow.cpp +0 -2
- esphome/components/fs3000/fs3000.cpp +0 -2
- esphome/components/ft5x06/touchscreen/ft5x06_touchscreen.cpp +0 -2
- esphome/components/ft63x6/ft63x6.cpp +0 -1
- esphome/components/gdk101/gdk101.cpp +0 -1
- esphome/components/gl_r01_i2c/gl_r01_i2c.cpp +0 -1
- esphome/components/gl_r01_i2c/sensor.py +1 -1
- esphome/components/gpio/one_wire/gpio_one_wire.cpp +0 -1
- esphome/components/gpio/switch/gpio_switch.cpp +0 -2
- esphome/components/gpio_expander/cached_gpio.h +24 -15
- esphome/components/gps/__init__.py +6 -2
- esphome/components/gps/gps.cpp +50 -49
- esphome/components/gps/gps.h +4 -8
- esphome/components/gps/time/gps_time.cpp +3 -9
- esphome/components/gps/time/gps_time.h +4 -7
- esphome/components/graph/__init__.py +1 -1
- esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.cpp +0 -1
- esphome/components/grove_tb6612fng/grove_tb6612fng.cpp +0 -1
- esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +21 -12
- esphome/components/gt911/touchscreen/gt911_touchscreen.h +26 -2
- esphome/components/haier/climate.py +5 -10
- esphome/components/haier/haier_base.cpp +0 -1
- esphome/components/hbridge/switch/hbridge_switch.cpp +0 -2
- esphome/components/hdc1080/hdc1080.cpp +0 -2
- esphome/components/heatpumpir/climate.py +2 -2
- esphome/components/hlw8012/hlw8012.cpp +0 -1
- esphome/components/hm3301/hm3301.cpp +0 -1
- esphome/components/hmc5883l/hmc5883l.cpp +0 -1
- esphome/components/homeassistant/__init__.py +1 -0
- esphome/components/homeassistant/number/__init__.py +1 -0
- esphome/components/homeassistant/number/homeassistant_number.cpp +11 -7
- esphome/components/homeassistant/switch/__init__.py +1 -0
- esphome/components/homeassistant/switch/homeassistant_switch.cpp +9 -5
- esphome/components/honeywellabp/honeywellabp.cpp +1 -4
- esphome/components/host/__init__.py +2 -0
- esphome/components/hte501/hte501.cpp +0 -1
- esphome/components/http_request/__init__.py +2 -3
- esphome/components/http_request/http_request_idf.cpp +2 -2
- esphome/components/htu21d/htu21d.cpp +0 -2
- esphome/components/htu31d/htu31d.cpp +0 -2
- esphome/components/hx711/hx711.cpp +0 -1
- esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +0 -1
- esphome/components/hydreon_rgxx/sensor.py +4 -5
- esphome/components/i2c/i2c_bus.h +1 -1
- esphome/components/i2c/i2c_bus_arduino.cpp +1 -2
- esphome/components/i2c/i2c_bus_esp_idf.cpp +192 -17
- esphome/components/i2c/i2c_bus_esp_idf.h +11 -1
- esphome/components/i2s_audio/__init__.py +6 -5
- esphome/components/i2s_audio/i2s_audio.cpp +0 -2
- esphome/components/i2s_audio/media_player/i2s_audio_media_player.cpp +1 -4
- esphome/components/i2s_audio/microphone/__init__.py +4 -6
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +0 -1
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +2 -2
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +273 -269
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +19 -34
- esphome/components/ili9xxx/display.py +4 -3
- esphome/components/ili9xxx/ili9xxx_display.cpp +0 -2
- esphome/components/image/__init__.py +123 -92
- esphome/components/improv_serial/__init__.py +7 -8
- esphome/components/ina219/ina219.cpp +0 -1
- esphome/components/ina226/ina226.cpp +0 -2
- esphome/components/ina260/ina260.cpp +0 -2
- esphome/components/ina2xx_base/__init__.py +2 -5
- esphome/components/ina2xx_base/ina2xx_base.cpp +0 -2
- esphome/components/ina3221/ina3221.cpp +0 -1
- esphome/components/internal_temperature/internal_temperature.cpp +0 -2
- esphome/components/interval/interval.h +5 -9
- esphome/components/json/__init__.py +1 -1
- esphome/components/kmeteriso/kmeteriso.cpp +0 -2
- esphome/components/lc709203f/lc709203f.cpp +0 -2
- esphome/components/lcd_gpio/display.py +1 -3
- esphome/components/lcd_gpio/gpio_lcd_display.cpp +0 -1
- esphome/components/lcd_pcf8574/pcf8574_display.cpp +0 -1
- esphome/components/ld2410/__init__.py +4 -6
- esphome/components/ld2410/binary_sensor.py +4 -0
- esphome/components/ld2410/ld2410.cpp +56 -100
- esphome/components/ld2410/ld2410.h +17 -15
- esphome/components/ld2410/sensor.py +24 -10
- esphome/components/ld2412/__init__.py +46 -0
- esphome/components/ld2412/binary_sensor.py +70 -0
- esphome/components/ld2412/button/__init__.py +74 -0
- esphome/components/ld2412/button/factory_reset_button.cpp +9 -0
- esphome/components/ld2412/button/factory_reset_button.h +18 -0
- esphome/components/ld2412/button/query_button.cpp +9 -0
- esphome/components/ld2412/button/query_button.h +18 -0
- esphome/components/ld2412/button/restart_button.cpp +9 -0
- esphome/components/ld2412/button/restart_button.h +18 -0
- esphome/components/ld2412/button/start_dynamic_background_correction_button.cpp +11 -0
- esphome/components/ld2412/button/start_dynamic_background_correction_button.h +18 -0
- esphome/components/ld2412/ld2412.cpp +861 -0
- esphome/components/ld2412/ld2412.h +141 -0
- esphome/components/ld2412/number/__init__.py +126 -0
- esphome/components/ld2412/number/gate_threshold_number.cpp +14 -0
- esphome/components/ld2412/number/gate_threshold_number.h +19 -0
- esphome/components/ld2412/number/light_threshold_number.cpp +12 -0
- esphome/components/ld2412/number/light_threshold_number.h +18 -0
- esphome/components/ld2412/number/max_distance_timeout_number.cpp +12 -0
- esphome/components/ld2412/number/max_distance_timeout_number.h +18 -0
- esphome/components/ld2412/select/__init__.py +82 -0
- esphome/components/ld2412/select/baud_rate_select.cpp +12 -0
- esphome/components/ld2412/select/baud_rate_select.h +18 -0
- esphome/components/ld2412/select/distance_resolution_select.cpp +12 -0
- esphome/components/ld2412/select/distance_resolution_select.h +18 -0
- esphome/components/ld2412/select/light_out_control_select.cpp +12 -0
- esphome/components/ld2412/select/light_out_control_select.h +18 -0
- esphome/components/ld2412/sensor.py +124 -0
- esphome/components/ld2412/switch/__init__.py +45 -0
- esphome/components/ld2412/switch/bluetooth_switch.cpp +12 -0
- esphome/components/ld2412/switch/bluetooth_switch.h +18 -0
- esphome/components/ld2412/switch/engineering_mode_switch.cpp +12 -0
- esphome/components/ld2412/switch/engineering_mode_switch.h +18 -0
- esphome/components/ld2412/text_sensor.py +34 -0
- esphome/components/ld2420/ld2420.cpp +0 -1
- esphome/components/ld2450/__init__.py +3 -4
- esphome/components/ld2450/binary_sensor.py +3 -0
- esphome/components/ld2450/ld2450.cpp +77 -165
- esphome/components/ld2450/ld2450.h +26 -54
- esphome/components/ld2450/sensor.py +120 -6
- esphome/components/ld2450/text_sensor.py +5 -4
- esphome/components/ld24xx/__init__.py +1 -0
- esphome/components/ld24xx/ld24xx.h +65 -0
- esphome/components/ledc/ledc_output.cpp +0 -1
- esphome/components/libretiny/__init__.py +2 -0
- esphome/components/light/__init__.py +0 -1
- esphome/components/light/effects.py +70 -45
- esphome/components/light/light_call.cpp +101 -66
- esphome/components/light/light_color_values.h +16 -11
- esphome/components/light/light_json_schema.cpp +46 -44
- esphome/components/light/light_state.cpp +8 -11
- esphome/components/light/light_traits.h +17 -0
- esphome/components/lightwaverf/lightwaverf.cpp +0 -2
- esphome/components/lilygo_t5_47/touchscreen/lilygo_t5_47_touchscreen.cpp +0 -1
- esphome/components/lock/__init__.py +0 -1
- esphome/components/logger/__init__.py +31 -9
- esphome/components/logger/logger.cpp +12 -7
- esphome/components/logger/logger.h +25 -14
- esphome/components/logger/logger_esp32.cpp +2 -7
- esphome/components/logger/logger_esp8266.cpp +2 -4
- esphome/components/logger/logger_host.cpp +2 -4
- esphome/components/logger/logger_libretiny.cpp +2 -4
- esphome/components/logger/logger_rp2040.cpp +2 -4
- esphome/components/logger/logger_zephyr.cpp +86 -0
- esphome/components/logger/select/logger_level_select.cpp +2 -4
- esphome/components/logger/select/logger_level_select.h +2 -4
- esphome/components/logger/task_log_buffer.cpp +2 -4
- esphome/components/logger/task_log_buffer.h +2 -4
- esphome/components/lps22/sensor.py +5 -5
- esphome/components/ltr390/ltr390.cpp +0 -2
- esphome/components/ltr501/ltr501.cpp +0 -1
- esphome/components/ltr_als_ps/ltr_als_ps.cpp +0 -1
- esphome/components/lvgl/__init__.py +14 -13
- esphome/components/lvgl/automation.py +2 -4
- esphome/components/lvgl/defines.py +0 -2
- esphome/components/lvgl/helpers.py +1 -1
- esphome/components/lvgl/lv_validation.py +7 -4
- esphome/components/lvgl/lvgl_esphome.cpp +2 -3
- esphome/components/lvgl/styles.py +2 -2
- esphome/components/lvgl/types.py +1 -1
- esphome/components/lvgl/widgets/__init__.py +2 -2
- esphome/components/lvgl/widgets/arc.py +14 -11
- esphome/components/lvgl/widgets/buttonmatrix.py +1 -1
- esphome/components/lvgl/widgets/qrcode.py +7 -7
- esphome/components/lvgl/widgets/spinner.py +6 -6
- esphome/components/lvgl/widgets/switch.py +2 -2
- esphome/components/lvgl/widgets/tabview.py +3 -3
- esphome/components/m5stack_8angle/m5stack_8angle.cpp +0 -1
- esphome/components/matrix_keypad/__init__.py +4 -3
- esphome/components/max17043/max17043.cpp +0 -2
- esphome/components/max31855/max31855.cpp +1 -4
- esphome/components/max31856/max31856.cpp +0 -4
- esphome/components/max31865/max31865.cpp +0 -1
- esphome/components/max44009/max44009.cpp +0 -1
- esphome/components/max6675/max6675.cpp +1 -4
- esphome/components/max6956/max6956.cpp +0 -1
- esphome/components/max7219/max7219.cpp +0 -1
- esphome/components/max7219digit/display.py +1 -1
- esphome/components/max7219digit/max7219digit.cpp +0 -1
- esphome/components/max9611/max9611.cpp +0 -1
- esphome/components/mcp23008/__init__.py +1 -1
- esphome/components/mcp23008/mcp23008.cpp +0 -1
- esphome/components/mcp23016/mcp23016.cpp +0 -1
- esphome/components/mcp23017/__init__.py +1 -1
- esphome/components/mcp23017/mcp23017.cpp +0 -1
- esphome/components/mcp23s08/__init__.py +1 -1
- esphome/components/mcp23s08/mcp23s08.cpp +0 -1
- esphome/components/mcp23s17/__init__.py +1 -1
- esphome/components/mcp23s17/mcp23s17.cpp +0 -1
- esphome/components/mcp23x08_base/__init__.py +2 -0
- esphome/components/mcp23x08_base/mcp23x08_base.cpp +9 -7
- esphome/components/mcp23x08_base/mcp23x08_base.h +9 -4
- esphome/components/mcp23x17_base/__init__.py +2 -0
- esphome/components/mcp23x17_base/mcp23x17_base.cpp +20 -7
- esphome/components/mcp23x17_base/mcp23x17_base.h +9 -4
- esphome/components/mcp23xxx_base/__init__.py +11 -5
- esphome/components/mcp23xxx_base/mcp23xxx_base.cpp +15 -12
- esphome/components/mcp23xxx_base/mcp23xxx_base.h +8 -7
- esphome/components/mcp3008/mcp3008.cpp +1 -4
- esphome/components/mcp3204/mcp3204.cpp +1 -4
- esphome/components/mcp4461/mcp4461.cpp +0 -1
- esphome/components/mcp4725/mcp4725.cpp +0 -1
- esphome/components/mcp4728/mcp4728.cpp +0 -1
- esphome/components/mcp9600/mcp9600.cpp +0 -2
- esphome/components/mcp9808/mcp9808.cpp +0 -2
- esphome/components/mdns/__init__.py +3 -0
- esphome/components/mdns/mdns_component.cpp +2 -0
- esphome/components/mdns/mdns_component.h +4 -0
- esphome/components/media_player/__init__.py +40 -0
- esphome/components/media_player/automation.h +16 -0
- esphome/components/media_player/media_player.cpp +13 -0
- esphome/components/media_player/media_player.h +50 -3
- esphome/components/micro_wake_word/micro_wake_word.cpp +0 -3
- esphome/components/mics_4514/mics_4514.cpp +1 -6
- esphome/components/midea/ir_transmitter.h +4 -4
- esphome/components/mipi/__init__.py +416 -0
- esphome/components/mipi_dsi/__init__.py +5 -0
- esphome/components/mipi_dsi/display.py +233 -0
- esphome/components/mipi_dsi/mipi_dsi.cpp +379 -0
- esphome/components/mipi_dsi/mipi_dsi.h +123 -0
- esphome/components/mipi_dsi/models/__init__.py +0 -0
- esphome/components/mipi_dsi/models/guition.py +38 -0
- esphome/components/mipi_dsi/models/m5stack.py +57 -0
- esphome/components/mipi_dsi/models/waveshare.py +105 -0
- esphome/components/mipi_rgb/models/lilygo.py +0 -0
- esphome/components/mipi_spi/__init__.py +0 -9
- esphome/components/mipi_spi/display.py +220 -256
- esphome/components/mipi_spi/mipi_spi.cpp +1 -485
- esphome/components/mipi_spi/mipi_spi.h +556 -108
- esphome/components/mipi_spi/models/__init__.py +0 -65
- esphome/components/mipi_spi/models/adafruit.py +30 -0
- esphome/components/mipi_spi/models/amoled.py +41 -5
- esphome/components/mipi_spi/models/ili.py +5 -5
- esphome/components/mipi_spi/models/jc.py +1 -3
- esphome/components/mipi_spi/models/lilygo.py +1 -1
- esphome/components/mipi_spi/models/waveshare.py +16 -1
- esphome/components/mixer/speaker/__init__.py +4 -5
- esphome/components/mlx90393/sensor.py +7 -5
- esphome/components/mlx90393/sensor_mlx90393.cpp +0 -1
- esphome/components/mlx90614/mlx90614.cpp +0 -1
- esphome/components/mmc5603/mmc5603.cpp +0 -1
- esphome/components/mmc5983/mmc5983.cpp +0 -2
- esphome/components/mpl3115a2/mpl3115a2.cpp +0 -2
- esphome/components/mpr121/__init__.py +7 -6
- esphome/components/mpr121/mpr121.cpp +0 -1
- esphome/components/mpu6050/mpu6050.cpp +0 -1
- esphome/components/mpu6886/mpu6886.cpp +0 -1
- esphome/components/mqtt/__init__.py +1 -2
- esphome/components/mqtt/mqtt_button.cpp +1 -1
- esphome/components/mqtt/mqtt_client.cpp +0 -1
- esphome/components/mqtt/mqtt_component.cpp +8 -14
- esphome/components/mqtt/mqtt_component.h +0 -7
- esphome/components/mqtt/mqtt_sensor.cpp +0 -1
- esphome/components/mqtt/mqtt_sensor.h +0 -1
- esphome/components/mqtt/mqtt_text_sensor.cpp +0 -1
- esphome/components/mqtt/mqtt_text_sensor.h +0 -1
- esphome/components/ms5611/ms5611.cpp +0 -1
- esphome/components/ms8607/ms8607.cpp +0 -1
- esphome/components/msa3xx/msa3xx.cpp +0 -2
- esphome/components/my9231/my9231.cpp +0 -2
- esphome/components/nau7802/nau7802.cpp +0 -1
- esphome/components/neopixelbus/light.py +3 -0
- esphome/components/network/util.cpp +29 -0
- esphome/components/nextion/nextion.cpp +0 -1
- esphome/components/nfc/binary_sensor/{binary_sensor.cpp → nfc_binary_sensor.cpp} +1 -1
- esphome/components/npi19/npi19.cpp +0 -2
- esphome/components/nrf52/__init__.py +223 -0
- esphome/components/nrf52/boards.py +34 -0
- esphome/components/nrf52/const.py +18 -0
- esphome/components/nrf52/gpio.py +79 -0
- esphome/components/number/__init__.py +2 -1
- esphome/components/one_wire/__init__.py +1 -2
- esphome/components/one_wire/one_wire.cpp +0 -2
- esphome/components/one_wire/one_wire.h +0 -2
- esphome/components/opentherm/hub.cpp +0 -1
- esphome/components/opentherm/number/__init__.py +2 -2
- esphome/components/openthread/__init__.py +2 -3
- esphome/components/openthread/openthread.cpp +30 -13
- esphome/components/openthread/openthread.h +3 -0
- esphome/components/openthread/openthread_esp.cpp +3 -1
- esphome/components/opt3001/sensor.py +2 -6
- esphome/components/output/__init__.py +38 -0
- esphome/components/output/automation.h +24 -0
- esphome/components/output/switch/output_switch.cpp +0 -2
- esphome/components/packages/__init__.py +1 -2
- esphome/components/packet_transport/__init__.py +4 -3
- esphome/components/pca6416a/pca6416a.cpp +0 -1
- esphome/components/pca9554/pca9554.cpp +0 -1
- esphome/components/pca9685/pca9685_output.cpp +0 -2
- esphome/components/pcf85063/pcf85063.cpp +0 -1
- esphome/components/pcf8563/pcf8563.cpp +0 -1
- esphome/components/pcf8574/pcf8574.cpp +0 -1
- esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +0 -1
- esphome/components/pipsolar/sensor/__init__.py +1 -1
- esphome/components/pm2005/pm2005.cpp +0 -1
- esphome/components/pmsa003i/pmsa003i.cpp +0 -2
- esphome/components/pmwcs3/sensor.py +1 -2
- esphome/components/pn532/pn532.cpp +0 -2
- esphome/components/pn532_spi/pn532_spi.cpp +0 -2
- esphome/components/power_supply/power_supply.cpp +7 -10
- esphome/components/power_supply/power_supply.h +1 -1
- esphome/components/psram/__init__.py +6 -1
- esphome/components/pulse_counter/pulse_counter_sensor.cpp +0 -1
- esphome/components/pulse_counter/sensor.py +9 -6
- esphome/components/pylontech/pylontech.cpp +0 -1
- esphome/components/qmc5883l/qmc5883l.cpp +0 -1
- esphome/components/qmp6988/qmp6988.cpp +0 -2
- esphome/components/qspi_dbi/display.py +2 -3
- esphome/components/qspi_dbi/qspi_dbi.cpp +0 -2
- esphome/components/qwiic_pir/binary_sensor.py +2 -3
- esphome/components/qwiic_pir/qwiic_pir.cpp +0 -2
- esphome/components/rc522/rc522.cpp +9 -31
- esphome/components/rc522_spi/rc522_spi.cpp +0 -1
- esphome/components/remote_base/__init__.py +5 -6
- esphome/components/remote_receiver/remote_receiver_esp32.cpp +0 -1
- esphome/components/remote_receiver/remote_receiver_esp8266.cpp +0 -1
- esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -1
- esphome/components/remote_transmitter/__init__.py +26 -0
- esphome/components/remote_transmitter/automation.h +18 -0
- esphome/components/remote_transmitter/remote_transmitter.h +2 -1
- esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +0 -1
- esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +2 -0
- esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +2 -0
- esphome/components/resampler/speaker/__init__.py +4 -5
- esphome/components/rf_bridge/__init__.py +4 -8
- esphome/components/rotary_encoder/rotary_encoder.cpp +0 -2
- esphome/components/rp2040/__init__.py +3 -1
- esphome/components/rp2040_pio_led_strip/led_strip.cpp +0 -2
- esphome/components/rp2040_pio_led_strip/light.py +1 -2
- esphome/components/rp2040_pwm/rp2040_pwm.cpp +1 -5
- esphome/components/rpi_dpi_rgb/display.py +13 -15
- esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +0 -3
- esphome/components/runtime_stats/__init__.py +34 -0
- esphome/components/runtime_stats/runtime_stats.cpp +102 -0
- esphome/components/runtime_stats/runtime_stats.h +132 -0
- esphome/components/scd30/scd30.cpp +0 -2
- esphome/components/scd30/sensor.py +1 -2
- esphome/components/scd4x/scd4x.cpp +0 -1
- esphome/components/scd4x/sensor.py +1 -3
- esphome/components/sdl/display.py +3 -1
- esphome/components/sdl/sdl_esphome.cpp +0 -2
- esphome/components/sdp3x/sdp3x.cpp +0 -2
- esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.cpp +0 -2
- esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp +0 -3
- esphome/components/select/__init__.py +2 -3
- esphome/components/select/select_traits.cpp +1 -1
- esphome/components/select/select_traits.h +1 -1
- esphome/components/sen0321/sen0321.cpp +0 -1
- esphome/components/sen5x/sen5x.cpp +0 -2
- esphome/components/sensor/__init__.py +36 -4
- esphome/components/sensor/filter.cpp +49 -10
- esphome/components/sensor/filter.h +22 -7
- esphome/components/sensor/sensor.cpp +0 -1
- esphome/components/sensor/sensor.h +0 -9
- esphome/components/sfa30/sfa30.cpp +0 -4
- esphome/components/sgp30/sgp30.cpp +0 -2
- esphome/components/sgp4x/sensor.py +1 -1
- esphome/components/sgp4x/sgp4x.cpp +0 -2
- esphome/components/shelly_dimmer/shelly_dimmer.cpp +0 -2
- esphome/components/sht3xd/sht3xd.cpp +0 -2
- esphome/components/sht4x/sht4x.cpp +0 -2
- esphome/components/shtcx/shtcx.cpp +0 -1
- esphome/components/sim800l/__init__.py +2 -4
- esphome/components/sm16716/sm16716.cpp +0 -1
- esphome/components/sm2135/sm2135.cpp +0 -1
- esphome/components/sm2235/sm2235.cpp +0 -1
- esphome/components/sm2335/sm2335.cpp +0 -1
- esphome/components/sn74hc165/sn74hc165.cpp +0 -1
- esphome/components/sn74hc595/sn74hc595.cpp +0 -1
- esphome/components/sntp/sntp_component.cpp +0 -1
- esphome/components/sound_level/sensor.py +1 -1
- esphome/components/speaker/media_player/__init__.py +21 -33
- esphome/components/speaker/media_player/audio_pipeline.cpp +4 -7
- esphome/components/spi/__init__.py +29 -13
- esphome/components/spi/spi.cpp +0 -2
- esphome/components/spi_device/spi_device.cpp +1 -4
- esphome/components/sprinkler/__init__.py +4 -4
- esphome/components/sps30/sps30.cpp +0 -1
- esphome/components/ssd1306_base/__init__.py +11 -11
- esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
- esphome/components/ssd1306_i2c/ssd1306_i2c.cpp +0 -1
- esphome/components/ssd1306_spi/ssd1306_spi.cpp +0 -1
- esphome/components/ssd1322_spi/ssd1322_spi.cpp +0 -1
- esphome/components/ssd1325_spi/ssd1325_spi.cpp +0 -1
- esphome/components/ssd1327_i2c/ssd1327_i2c.cpp +0 -1
- esphome/components/ssd1327_spi/ssd1327_spi.cpp +0 -1
- esphome/components/ssd1331_spi/ssd1331_spi.cpp +0 -1
- esphome/components/ssd1351_spi/ssd1351_spi.cpp +0 -1
- esphome/components/st7567_i2c/st7567_i2c.cpp +0 -1
- esphome/components/st7567_spi/st7567_spi.cpp +0 -1
- esphome/components/st7701s/display.py +10 -14
- esphome/components/st7701s/st7701s.cpp +0 -3
- esphome/components/st7735/st7735.cpp +0 -1
- esphome/components/st7789v/st7789v.cpp +0 -1
- esphome/components/st7920/st7920.cpp +0 -1
- esphome/components/status_led/light/status_led_light.cpp +0 -2
- esphome/components/status_led/status_led.cpp +0 -1
- esphome/components/stepper/__init__.py +2 -4
- esphome/components/sts3x/sts3x.cpp +0 -1
- esphome/components/substitutions/__init__.py +10 -16
- esphome/components/substitutions/jinja.py +24 -1
- esphome/components/sun/__init__.py +2 -3
- esphome/components/switch/__init__.py +31 -1
- esphome/components/switch/automation.h +24 -0
- esphome/components/switch/switch.cpp +8 -0
- esphome/components/switch/switch.h +8 -0
- esphome/components/sx126x/sx126x.cpp +0 -2
- esphome/components/sx127x/sx127x.cpp +0 -2
- esphome/components/sx1509/__init__.py +7 -5
- esphome/components/sx1509/output/sx1509_float_output.cpp +1 -1
- esphome/components/sx1509/sx1509.cpp +0 -2
- esphome/components/syslog/esphome_syslog.cpp +1 -1
- esphome/components/tc74/tc74.cpp +0 -1
- esphome/components/tca9548a/tca9548a.cpp +0 -1
- esphome/components/tca9555/tca9555.cpp +0 -1
- esphome/components/tcs34725/tcs34725.cpp +0 -1
- esphome/components/tee501/tee501.cpp +0 -1
- esphome/components/tem3200/tem3200.cpp +0 -2
- esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +0 -1
- esphome/components/template/cover/template_cover.cpp +0 -1
- esphome/components/template/select/template_select.cpp +0 -1
- esphome/components/template/text/template_text.cpp +0 -2
- esphome/components/template/valve/template_valve.cpp +0 -1
- esphome/components/text/__init__.py +0 -1
- esphome/components/text/text_traits.h +2 -0
- esphome/components/text_sensor/__init__.py +2 -1
- esphome/components/text_sensor/text_sensor.cpp +0 -2
- esphome/components/text_sensor/text_sensor.h +0 -8
- esphome/components/thermostat/climate.py +4 -4
- esphome/components/time/__init__.py +7 -4
- esphome/components/time/real_time_clock.cpp +16 -3
- esphome/components/tlc59208f/tlc59208f_output.cpp +0 -2
- esphome/components/tlc5947/tlc5947.cpp +0 -2
- esphome/components/tlc5971/tlc5971.cpp +0 -2
- esphome/components/tm1621/tm1621.cpp +0 -2
- esphome/components/tm1637/tm1637.cpp +0 -2
- esphome/components/tm1638/tm1638.cpp +0 -2
- esphome/components/tm1651/__init__.py +45 -48
- esphome/components/tm1651/tm1651.cpp +213 -47
- esphome/components/tm1651/tm1651.h +37 -32
- esphome/components/tmp117/tmp117.cpp +0 -2
- esphome/components/tsl2561/tsl2561.cpp +0 -1
- esphome/components/tsl2591/tsl2591.cpp +0 -1
- esphome/components/tt21100/touchscreen/tt21100.cpp +0 -2
- esphome/components/ttp229_bsf/ttp229_bsf.cpp +0 -1
- esphome/components/ttp229_lsf/ttp229_lsf.cpp +0 -1
- esphome/components/tuya/climate/__init__.py +9 -10
- esphome/components/tuya/number/__init__.py +8 -6
- esphome/components/tx20/tx20.cpp +0 -1
- esphome/components/uart/uart_component_esp32_arduino.cpp +0 -1
- esphome/components/uart/uart_component_esp8266.cpp +0 -1
- esphome/components/uart/uart_component_esp_idf.cpp +0 -2
- esphome/components/uart/uart_component_libretiny.cpp +0 -2
- esphome/components/uart/uart_component_rp2040.cpp +0 -2
- esphome/components/udp/__init__.py +1 -1
- esphome/components/ufire_ec/sensor.py +1 -2
- esphome/components/ufire_ec/ufire_ec.cpp +0 -2
- esphome/components/ufire_ise/sensor.py +1 -2
- esphome/components/ufire_ise/ufire_ise.cpp +0 -2
- esphome/components/ultrasonic/ultrasonic_sensor.cpp +0 -1
- esphome/components/update/__init__.py +0 -1
- esphome/components/uptime/sensor/uptime_seconds_sensor.cpp +0 -1
- esphome/components/uptime/sensor/uptime_seconds_sensor.h +0 -2
- esphome/components/usb_host/usb_host_client.cpp +0 -1
- esphome/components/usb_host/usb_host_component.cpp +0 -1
- esphome/components/valve/__init__.py +0 -1
- esphome/components/veml3235/veml3235.cpp +0 -3
- esphome/components/veml7700/veml7700.cpp +0 -2
- esphome/components/version/version_text_sensor.cpp +0 -1
- esphome/components/version/version_text_sensor.h +0 -1
- esphome/components/vl53l0x/vl53l0x_sensor.cpp +0 -4
- esphome/components/voice_assistant/voice_assistant.cpp +9 -8
- esphome/components/web_server/__init__.py +13 -0
- esphome/components/web_server/web_server.cpp +187 -352
- esphome/components/web_server/web_server.h +61 -1
- esphome/components/web_server_base/__init__.py +1 -1
- esphome/components/web_server_base/web_server_base.cpp +2 -0
- esphome/components/web_server_base/web_server_base.h +6 -0
- esphome/components/web_server_idf/web_server_idf.cpp +10 -8
- esphome/components/web_server_idf/web_server_idf.h +2 -0
- esphome/components/weikai_i2c/weikai_i2c.cpp +1 -2
- esphome/components/weikai_spi/weikai_spi.cpp +1 -1
- esphome/components/wifi/__init__.py +8 -43
- esphome/components/wifi/wifi_component.cpp +100 -36
- esphome/components/wifi/wifi_component.h +5 -1
- esphome/components/wifi/wifi_component_esp32_arduino.cpp +30 -0
- esphome/components/wifi/wifi_component_esp_idf.cpp +30 -0
- esphome/components/wifi_info/wifi_info_text_sensor.h +0 -6
- esphome/components/wifi_signal/wifi_signal_sensor.h +0 -1
- esphome/components/wireguard/wireguard.cpp +0 -2
- esphome/components/x9c/x9c.cpp +0 -2
- esphome/components/xgzp68xx/xgzp68xx.cpp +0 -1
- esphome/components/xl9535/xl9535.cpp +0 -2
- esphome/components/zephyr/__init__.py +252 -0
- esphome/components/zephyr/const.py +16 -0
- esphome/components/zephyr/core.cpp +90 -0
- esphome/components/zephyr/gpio.cpp +120 -0
- esphome/components/zephyr/gpio.h +38 -0
- esphome/components/zephyr/pre_build.py.script +4 -0
- esphome/components/zephyr/preferences.cpp +156 -0
- esphome/components/zephyr/preferences.h +13 -0
- esphome/config.py +38 -16
- esphome/config_helpers.py +1 -2
- esphome/config_validation.py +12 -16
- esphome/const.py +26 -1
- esphome/core/__init__.py +88 -51
- esphome/core/application.cpp +75 -21
- esphome/core/application.h +106 -171
- esphome/core/color.h +10 -0
- esphome/core/component.cpp +41 -25
- esphome/core/component.h +9 -6
- esphome/core/component_iterator.cpp +61 -261
- esphome/core/component_iterator.h +15 -0
- esphome/core/config.py +26 -11
- esphome/core/defines.h +40 -2
- esphome/core/entity_base.h +18 -0
- esphome/core/entity_helpers.py +45 -10
- esphome/core/helpers.cpp +8 -15
- esphome/core/helpers.h +60 -6
- esphome/core/lock_free_queue.h +1 -1
- esphome/core/scheduler.cpp +277 -74
- esphome/core/scheduler.h +89 -27
- esphome/cpp_generator.py +2 -6
- esphome/cpp_helpers.py +1 -1
- esphome/dashboard/dashboard.py +2 -3
- esphome/dashboard/dns.py +2 -8
- esphome/dashboard/web_server.py +34 -19
- esphome/espota2.py +1 -4
- esphome/git.py +3 -1
- esphome/helpers.py +23 -4
- esphome/log.py +3 -1
- esphome/mqtt.py +3 -5
- esphome/platformio_api.py +7 -4
- esphome/types.py +12 -0
- esphome/util.py +20 -8
- esphome/voluptuous_schema.py +4 -3
- esphome/vscode.py +1 -2
- esphome/wizard.py +1 -4
- esphome/writer.py +5 -107
- esphome/yaml_util.py +7 -5
- {esphome-2025.7.5.dist-info → esphome-2025.8.0b2.dist-info}/METADATA +13 -14
- {esphome-2025.7.5.dist-info → esphome-2025.8.0b2.dist-info}/RECORD +751 -671
- esphome/components/mipi_spi/models/commands.py +0 -82
- /esphome/components/nfc/binary_sensor/{binary_sensor.h → nfc_binary_sensor.h} +0 -0
- {esphome-2025.7.5.dist-info → esphome-2025.8.0b2.dist-info}/WHEEL +0 -0
- {esphome-2025.7.5.dist-info → esphome-2025.8.0b2.dist-info}/entry_points.txt +0 -0
- {esphome-2025.7.5.dist-info → esphome-2025.8.0b2.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.7.5.dist-info → esphome-2025.8.0b2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
#include "espnow_component.h"
|
|
2
|
+
|
|
3
|
+
#ifdef USE_ESP32
|
|
4
|
+
|
|
5
|
+
#include "espnow_err.h"
|
|
6
|
+
|
|
7
|
+
#include "esphome/core/defines.h"
|
|
8
|
+
#include "esphome/core/log.h"
|
|
9
|
+
|
|
10
|
+
#include <esp_event.h>
|
|
11
|
+
#include <esp_mac.h>
|
|
12
|
+
#include <esp_now.h>
|
|
13
|
+
#include <esp_random.h>
|
|
14
|
+
#include <esp_wifi.h>
|
|
15
|
+
#include <cstring>
|
|
16
|
+
#include <memory>
|
|
17
|
+
|
|
18
|
+
#ifdef USE_WIFI
|
|
19
|
+
#include "esphome/components/wifi/wifi_component.h"
|
|
20
|
+
#endif
|
|
21
|
+
|
|
22
|
+
namespace esphome::espnow {
|
|
23
|
+
|
|
24
|
+
static constexpr const char *TAG = "espnow";
|
|
25
|
+
|
|
26
|
+
static const esp_err_t CONFIG_ESPNOW_WAKE_WINDOW = 50;
|
|
27
|
+
static const esp_err_t CONFIG_ESPNOW_WAKE_INTERVAL = 100;
|
|
28
|
+
|
|
29
|
+
ESPNowComponent *global_esp_now = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
|
30
|
+
|
|
31
|
+
static const LogString *espnow_error_to_str(esp_err_t error) {
|
|
32
|
+
switch (error) {
|
|
33
|
+
case ESP_ERR_ESPNOW_FAILED:
|
|
34
|
+
return LOG_STR("ESPNow is in fail mode");
|
|
35
|
+
case ESP_ERR_ESPNOW_OWN_ADDRESS:
|
|
36
|
+
return LOG_STR("Message to your self");
|
|
37
|
+
case ESP_ERR_ESPNOW_DATA_SIZE:
|
|
38
|
+
return LOG_STR("Data size to large");
|
|
39
|
+
case ESP_ERR_ESPNOW_PEER_NOT_SET:
|
|
40
|
+
return LOG_STR("Peer address not set");
|
|
41
|
+
case ESP_ERR_ESPNOW_PEER_NOT_PAIRED:
|
|
42
|
+
return LOG_STR("Peer address not paired");
|
|
43
|
+
case ESP_ERR_ESPNOW_NOT_INIT:
|
|
44
|
+
return LOG_STR("Not init");
|
|
45
|
+
case ESP_ERR_ESPNOW_ARG:
|
|
46
|
+
return LOG_STR("Invalid argument");
|
|
47
|
+
case ESP_ERR_ESPNOW_INTERNAL:
|
|
48
|
+
return LOG_STR("Internal Error");
|
|
49
|
+
case ESP_ERR_ESPNOW_NO_MEM:
|
|
50
|
+
return LOG_STR("Our of memory");
|
|
51
|
+
case ESP_ERR_ESPNOW_NOT_FOUND:
|
|
52
|
+
return LOG_STR("Peer not found");
|
|
53
|
+
case ESP_ERR_ESPNOW_IF:
|
|
54
|
+
return LOG_STR("Interface does not match");
|
|
55
|
+
case ESP_OK:
|
|
56
|
+
return LOG_STR("OK");
|
|
57
|
+
case ESP_NOW_SEND_FAIL:
|
|
58
|
+
return LOG_STR("Failed");
|
|
59
|
+
default:
|
|
60
|
+
return LOG_STR("Unknown Error");
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
std::string peer_str(uint8_t *peer) {
|
|
65
|
+
if (peer == nullptr || peer[0] == 0) {
|
|
66
|
+
return "[Not Set]";
|
|
67
|
+
} else if (memcmp(peer, ESPNOW_BROADCAST_ADDR, ESP_NOW_ETH_ALEN) == 0) {
|
|
68
|
+
return "[Broadcast]";
|
|
69
|
+
} else if (memcmp(peer, ESPNOW_MULTICAST_ADDR, ESP_NOW_ETH_ALEN) == 0) {
|
|
70
|
+
return "[Multicast]";
|
|
71
|
+
} else {
|
|
72
|
+
return format_mac_address_pretty(peer);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
|
|
77
|
+
void on_send_report(const esp_now_send_info_t *info, esp_now_send_status_t status)
|
|
78
|
+
#else
|
|
79
|
+
void on_send_report(const uint8_t *mac_addr, esp_now_send_status_t status)
|
|
80
|
+
#endif
|
|
81
|
+
{
|
|
82
|
+
// Allocate an event from the pool
|
|
83
|
+
ESPNowPacket *packet = global_esp_now->receive_packet_pool_.allocate();
|
|
84
|
+
if (packet == nullptr) {
|
|
85
|
+
// No events available - queue is full or we're out of memory
|
|
86
|
+
global_esp_now->receive_packet_queue_.increment_dropped_count();
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Load new packet data (replaces previous packet)
|
|
91
|
+
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
|
|
92
|
+
packet->load_sent_data(info->des_addr, status);
|
|
93
|
+
#else
|
|
94
|
+
packet->load_sent_data(mac_addr, status);
|
|
95
|
+
#endif
|
|
96
|
+
|
|
97
|
+
// Push the packet to the queue
|
|
98
|
+
global_esp_now->receive_packet_queue_.push(packet);
|
|
99
|
+
// Push always because we're the only producer and the pool ensures we never exceed queue size
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
void on_data_received(const esp_now_recv_info_t *info, const uint8_t *data, int size) {
|
|
103
|
+
// Allocate an event from the pool
|
|
104
|
+
ESPNowPacket *packet = global_esp_now->receive_packet_pool_.allocate();
|
|
105
|
+
if (packet == nullptr) {
|
|
106
|
+
// No events available - queue is full or we're out of memory
|
|
107
|
+
global_esp_now->receive_packet_queue_.increment_dropped_count();
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Load new packet data (replaces previous packet)
|
|
112
|
+
packet->load_received_data(info, data, size);
|
|
113
|
+
|
|
114
|
+
// Push the packet to the queue
|
|
115
|
+
global_esp_now->receive_packet_queue_.push(packet);
|
|
116
|
+
// Push always because we're the only producer and the pool ensures we never exceed queue size
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
ESPNowComponent::ESPNowComponent() { global_esp_now = this; }
|
|
120
|
+
|
|
121
|
+
void ESPNowComponent::dump_config() {
|
|
122
|
+
uint32_t version = 0;
|
|
123
|
+
esp_now_get_version(&version);
|
|
124
|
+
|
|
125
|
+
ESP_LOGCONFIG(TAG, "espnow:");
|
|
126
|
+
if (this->is_disabled()) {
|
|
127
|
+
ESP_LOGCONFIG(TAG, " Disabled");
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
ESP_LOGCONFIG(TAG,
|
|
131
|
+
" Own address: %s\n"
|
|
132
|
+
" Version: v%" PRIu32 "\n"
|
|
133
|
+
" Wi-Fi channel: %d",
|
|
134
|
+
format_mac_address_pretty(this->own_address_).c_str(), version, this->wifi_channel_);
|
|
135
|
+
#ifdef USE_WIFI
|
|
136
|
+
ESP_LOGCONFIG(TAG, " Wi-Fi enabled: %s", YESNO(this->is_wifi_enabled()));
|
|
137
|
+
#endif
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
bool ESPNowComponent::is_wifi_enabled() {
|
|
141
|
+
#ifdef USE_WIFI
|
|
142
|
+
return wifi::global_wifi_component != nullptr && !wifi::global_wifi_component->is_disabled();
|
|
143
|
+
#else
|
|
144
|
+
return false;
|
|
145
|
+
#endif
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
void ESPNowComponent::setup() {
|
|
149
|
+
if (this->enable_on_boot_) {
|
|
150
|
+
this->enable_();
|
|
151
|
+
} else {
|
|
152
|
+
this->state_ = ESPNOW_STATE_DISABLED;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
void ESPNowComponent::enable() {
|
|
157
|
+
if (this->state_ == ESPNOW_STATE_ENABLED)
|
|
158
|
+
return;
|
|
159
|
+
|
|
160
|
+
ESP_LOGD(TAG, "Enabling");
|
|
161
|
+
this->state_ = ESPNOW_STATE_OFF;
|
|
162
|
+
|
|
163
|
+
this->enable_();
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
void ESPNowComponent::enable_() {
|
|
167
|
+
if (!this->is_wifi_enabled()) {
|
|
168
|
+
esp_event_loop_create_default();
|
|
169
|
+
|
|
170
|
+
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
|
171
|
+
|
|
172
|
+
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
|
173
|
+
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
|
|
174
|
+
ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
|
|
175
|
+
ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE));
|
|
176
|
+
ESP_ERROR_CHECK(esp_wifi_start());
|
|
177
|
+
ESP_ERROR_CHECK(esp_wifi_disconnect());
|
|
178
|
+
|
|
179
|
+
this->apply_wifi_channel();
|
|
180
|
+
}
|
|
181
|
+
this->get_wifi_channel();
|
|
182
|
+
|
|
183
|
+
esp_err_t err = esp_now_init();
|
|
184
|
+
if (err != ESP_OK) {
|
|
185
|
+
ESP_LOGE(TAG, "esp_now_init failed: %s", esp_err_to_name(err));
|
|
186
|
+
this->mark_failed();
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
err = esp_now_register_recv_cb(on_data_received);
|
|
191
|
+
if (err != ESP_OK) {
|
|
192
|
+
ESP_LOGE(TAG, "esp_now_register_recv_cb failed: %s", esp_err_to_name(err));
|
|
193
|
+
this->mark_failed();
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
err = esp_now_register_send_cb(on_send_report);
|
|
198
|
+
if (err != ESP_OK) {
|
|
199
|
+
ESP_LOGE(TAG, "esp_now_register_recv_cb failed: %s", esp_err_to_name(err));
|
|
200
|
+
this->mark_failed();
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
esp_wifi_get_mac(WIFI_IF_STA, this->own_address_);
|
|
205
|
+
|
|
206
|
+
#ifdef USE_DEEP_SLEEP
|
|
207
|
+
esp_now_set_wake_window(CONFIG_ESPNOW_WAKE_WINDOW);
|
|
208
|
+
esp_wifi_connectionless_module_set_wake_interval(CONFIG_ESPNOW_WAKE_INTERVAL);
|
|
209
|
+
#endif
|
|
210
|
+
|
|
211
|
+
this->state_ = ESPNOW_STATE_ENABLED;
|
|
212
|
+
|
|
213
|
+
for (auto peer : this->peers_) {
|
|
214
|
+
this->add_peer(peer.address);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
void ESPNowComponent::disable() {
|
|
219
|
+
if (this->state_ == ESPNOW_STATE_DISABLED)
|
|
220
|
+
return;
|
|
221
|
+
|
|
222
|
+
ESP_LOGD(TAG, "Disabling");
|
|
223
|
+
this->state_ = ESPNOW_STATE_DISABLED;
|
|
224
|
+
|
|
225
|
+
esp_now_unregister_recv_cb();
|
|
226
|
+
esp_now_unregister_send_cb();
|
|
227
|
+
|
|
228
|
+
esp_err_t err = esp_now_deinit();
|
|
229
|
+
if (err != ESP_OK) {
|
|
230
|
+
ESP_LOGE(TAG, "esp_now_deinit failed! 0x%x", err);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
void ESPNowComponent::apply_wifi_channel() {
|
|
235
|
+
if (this->state_ == ESPNOW_STATE_DISABLED) {
|
|
236
|
+
ESP_LOGE(TAG, "Cannot set channel when ESPNOW disabled");
|
|
237
|
+
this->mark_failed();
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (this->is_wifi_enabled()) {
|
|
242
|
+
ESP_LOGE(TAG, "Cannot set channel when Wi-Fi enabled");
|
|
243
|
+
this->mark_failed();
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
ESP_LOGI(TAG, "Channel set to %d.", this->wifi_channel_);
|
|
248
|
+
esp_wifi_set_promiscuous(true);
|
|
249
|
+
esp_wifi_set_channel(this->wifi_channel_, WIFI_SECOND_CHAN_NONE);
|
|
250
|
+
esp_wifi_set_promiscuous(false);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
void ESPNowComponent::loop() {
|
|
254
|
+
#ifdef USE_WIFI
|
|
255
|
+
if (wifi::global_wifi_component != nullptr && wifi::global_wifi_component->is_connected()) {
|
|
256
|
+
int32_t new_channel = wifi::global_wifi_component->get_wifi_channel();
|
|
257
|
+
if (new_channel != this->wifi_channel_) {
|
|
258
|
+
ESP_LOGI(TAG, "Wifi Channel is changed from %d to %d.", this->wifi_channel_, new_channel);
|
|
259
|
+
this->wifi_channel_ = new_channel;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
#endif
|
|
263
|
+
// Process received packets
|
|
264
|
+
ESPNowPacket *packet = this->receive_packet_queue_.pop();
|
|
265
|
+
while (packet != nullptr) {
|
|
266
|
+
switch (packet->type_) {
|
|
267
|
+
case ESPNowPacket::RECEIVED: {
|
|
268
|
+
const ESPNowRecvInfo info = packet->get_receive_info();
|
|
269
|
+
if (!esp_now_is_peer_exist(info.src_addr)) {
|
|
270
|
+
bool handled = false;
|
|
271
|
+
for (auto *handler : this->unknown_peer_handlers_) {
|
|
272
|
+
if (handler->on_unknown_peer(info, packet->packet_.receive.data, packet->packet_.receive.size)) {
|
|
273
|
+
handled = true;
|
|
274
|
+
break; // If a handler returns true, stop processing further handlers
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if (!handled && this->auto_add_peer_) {
|
|
278
|
+
this->add_peer(info.src_addr);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
// Intentionally left as if instead of else in case the peer is added above
|
|
282
|
+
if (esp_now_is_peer_exist(info.src_addr)) {
|
|
283
|
+
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
|
|
284
|
+
ESP_LOGV(TAG, "<<< [%s -> %s] %s", format_mac_address_pretty(info.src_addr).c_str(),
|
|
285
|
+
format_mac_address_pretty(info.des_addr).c_str(),
|
|
286
|
+
format_hex_pretty(packet->packet_.receive.data, packet->packet_.receive.size).c_str());
|
|
287
|
+
#endif
|
|
288
|
+
if (memcmp(info.des_addr, ESPNOW_BROADCAST_ADDR, ESP_NOW_ETH_ALEN) == 0) {
|
|
289
|
+
for (auto *handler : this->broadcasted_handlers_) {
|
|
290
|
+
if (handler->on_broadcasted(info, packet->packet_.receive.data, packet->packet_.receive.size))
|
|
291
|
+
break; // If a handler returns true, stop processing further handlers
|
|
292
|
+
}
|
|
293
|
+
} else {
|
|
294
|
+
for (auto *handler : this->received_handlers_) {
|
|
295
|
+
if (handler->on_received(info, packet->packet_.receive.data, packet->packet_.receive.size))
|
|
296
|
+
break; // If a handler returns true, stop processing further handlers
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
case ESPNowPacket::SENT: {
|
|
303
|
+
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERBOSE
|
|
304
|
+
ESP_LOGV(TAG, ">>> [%s] %s", format_mac_address_pretty(packet->packet_.sent.address).c_str(),
|
|
305
|
+
LOG_STR_ARG(espnow_error_to_str(packet->packet_.sent.status)));
|
|
306
|
+
#endif
|
|
307
|
+
if (this->current_send_packet_ != nullptr) {
|
|
308
|
+
this->current_send_packet_->callback_(packet->packet_.sent.status);
|
|
309
|
+
this->send_packet_pool_.release(this->current_send_packet_);
|
|
310
|
+
this->current_send_packet_ = nullptr; // Reset current packet after sending
|
|
311
|
+
}
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
default:
|
|
315
|
+
break;
|
|
316
|
+
}
|
|
317
|
+
// Return the packet to the pool
|
|
318
|
+
this->receive_packet_pool_.release(packet);
|
|
319
|
+
packet = this->receive_packet_queue_.pop();
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Process sending packet queue
|
|
323
|
+
if (this->current_send_packet_ == nullptr) {
|
|
324
|
+
this->send_();
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
// Log dropped received packets periodically
|
|
328
|
+
uint16_t received_dropped = this->receive_packet_queue_.get_and_reset_dropped_count();
|
|
329
|
+
if (received_dropped > 0) {
|
|
330
|
+
ESP_LOGW(TAG, "Dropped %u received packets due to buffer overflow", received_dropped);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// Log dropped send packets periodically
|
|
334
|
+
uint16_t send_dropped = this->send_packet_queue_.get_and_reset_dropped_count();
|
|
335
|
+
if (send_dropped > 0) {
|
|
336
|
+
ESP_LOGW(TAG, "Dropped %u send packets due to buffer overflow", send_dropped);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
uint8_t ESPNowComponent::get_wifi_channel() {
|
|
341
|
+
wifi_second_chan_t dummy;
|
|
342
|
+
esp_wifi_get_channel(&this->wifi_channel_, &dummy);
|
|
343
|
+
return this->wifi_channel_;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
esp_err_t ESPNowComponent::send(const uint8_t *peer_address, const uint8_t *payload, size_t size,
|
|
347
|
+
const send_callback_t &callback) {
|
|
348
|
+
if (this->state_ != ESPNOW_STATE_ENABLED) {
|
|
349
|
+
return ESP_ERR_ESPNOW_NOT_INIT;
|
|
350
|
+
} else if (this->is_failed()) {
|
|
351
|
+
return ESP_ERR_ESPNOW_FAILED;
|
|
352
|
+
} else if (peer_address == 0ULL) {
|
|
353
|
+
return ESP_ERR_ESPNOW_PEER_NOT_SET;
|
|
354
|
+
} else if (memcmp(peer_address, this->own_address_, ESP_NOW_ETH_ALEN) == 0) {
|
|
355
|
+
return ESP_ERR_ESPNOW_OWN_ADDRESS;
|
|
356
|
+
} else if (size > ESP_NOW_MAX_DATA_LEN) {
|
|
357
|
+
return ESP_ERR_ESPNOW_DATA_SIZE;
|
|
358
|
+
} else if (!esp_now_is_peer_exist(peer_address)) {
|
|
359
|
+
if (memcmp(peer_address, ESPNOW_BROADCAST_ADDR, ESP_NOW_ETH_ALEN) == 0 || this->auto_add_peer_) {
|
|
360
|
+
esp_err_t err = this->add_peer(peer_address);
|
|
361
|
+
if (err != ESP_OK) {
|
|
362
|
+
return err;
|
|
363
|
+
}
|
|
364
|
+
} else {
|
|
365
|
+
return ESP_ERR_ESPNOW_PEER_NOT_PAIRED;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
// Allocate a packet from the pool
|
|
369
|
+
ESPNowSendPacket *packet = this->send_packet_pool_.allocate();
|
|
370
|
+
if (packet == nullptr) {
|
|
371
|
+
this->send_packet_queue_.increment_dropped_count();
|
|
372
|
+
ESP_LOGE(TAG, "Failed to allocate send packet from pool");
|
|
373
|
+
this->status_momentary_warning("send-packet-pool-full");
|
|
374
|
+
return ESP_ERR_ESPNOW_NO_MEM;
|
|
375
|
+
}
|
|
376
|
+
// Load the packet data
|
|
377
|
+
packet->load_data(peer_address, payload, size, callback);
|
|
378
|
+
// Push the packet to the send queue
|
|
379
|
+
this->send_packet_queue_.push(packet);
|
|
380
|
+
return ESP_OK;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
void ESPNowComponent::send_() {
|
|
384
|
+
ESPNowSendPacket *packet = this->send_packet_queue_.pop();
|
|
385
|
+
if (packet == nullptr) {
|
|
386
|
+
return; // No packets to send
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
this->current_send_packet_ = packet;
|
|
390
|
+
esp_err_t err = esp_now_send(packet->address_, packet->data_, packet->size_);
|
|
391
|
+
if (err != ESP_OK) {
|
|
392
|
+
ESP_LOGE(TAG, "Failed to send packet to %s - %s", format_mac_address_pretty(packet->address_).c_str(),
|
|
393
|
+
LOG_STR_ARG(espnow_error_to_str(err)));
|
|
394
|
+
if (packet->callback_ != nullptr) {
|
|
395
|
+
packet->callback_(err);
|
|
396
|
+
}
|
|
397
|
+
this->status_momentary_warning("send-failed");
|
|
398
|
+
this->send_packet_pool_.release(packet);
|
|
399
|
+
this->current_send_packet_ = nullptr; // Reset current packet
|
|
400
|
+
return;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
esp_err_t ESPNowComponent::add_peer(const uint8_t *peer) {
|
|
405
|
+
if (this->state_ != ESPNOW_STATE_ENABLED || this->is_failed()) {
|
|
406
|
+
return ESP_ERR_ESPNOW_NOT_INIT;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
if (memcmp(peer, this->own_address_, ESP_NOW_ETH_ALEN) == 0) {
|
|
410
|
+
this->status_momentary_warning("peer-add-failed");
|
|
411
|
+
return ESP_ERR_INVALID_MAC;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
if (!esp_now_is_peer_exist(peer)) {
|
|
415
|
+
esp_now_peer_info_t peer_info = {};
|
|
416
|
+
memset(&peer_info, 0, sizeof(esp_now_peer_info_t));
|
|
417
|
+
peer_info.ifidx = WIFI_IF_STA;
|
|
418
|
+
memcpy(peer_info.peer_addr, peer, ESP_NOW_ETH_ALEN);
|
|
419
|
+
esp_err_t err = esp_now_add_peer(&peer_info);
|
|
420
|
+
|
|
421
|
+
if (err != ESP_OK) {
|
|
422
|
+
ESP_LOGE(TAG, "Failed to add peer %s - %s", format_mac_address_pretty(peer).c_str(),
|
|
423
|
+
LOG_STR_ARG(espnow_error_to_str(err)));
|
|
424
|
+
this->status_momentary_warning("peer-add-failed");
|
|
425
|
+
return err;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
bool found = false;
|
|
429
|
+
for (auto &it : this->peers_) {
|
|
430
|
+
if (it == peer) {
|
|
431
|
+
found = true;
|
|
432
|
+
break;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
if (!found) {
|
|
436
|
+
ESPNowPeer new_peer;
|
|
437
|
+
memcpy(new_peer.address, peer, ESP_NOW_ETH_ALEN);
|
|
438
|
+
this->peers_.push_back(new_peer);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
return ESP_OK;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
esp_err_t ESPNowComponent::del_peer(const uint8_t *peer) {
|
|
445
|
+
if (this->state_ != ESPNOW_STATE_ENABLED || this->is_failed()) {
|
|
446
|
+
return ESP_ERR_ESPNOW_NOT_INIT;
|
|
447
|
+
}
|
|
448
|
+
if (esp_now_is_peer_exist(peer)) {
|
|
449
|
+
esp_err_t err = esp_now_del_peer(peer);
|
|
450
|
+
if (err != ESP_OK) {
|
|
451
|
+
ESP_LOGE(TAG, "Failed to delete peer %s - %s", format_mac_address_pretty(peer).c_str(),
|
|
452
|
+
LOG_STR_ARG(espnow_error_to_str(err)));
|
|
453
|
+
this->status_momentary_warning("peer-del-failed");
|
|
454
|
+
return err;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
for (auto it = this->peers_.begin(); it != this->peers_.end(); ++it) {
|
|
458
|
+
if (*it == peer) {
|
|
459
|
+
this->peers_.erase(it);
|
|
460
|
+
break;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
return ESP_OK;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
} // namespace esphome::espnow
|
|
467
|
+
|
|
468
|
+
#endif // USE_ESP32
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "esphome/core/automation.h"
|
|
4
|
+
#include "esphome/core/component.h"
|
|
5
|
+
|
|
6
|
+
#ifdef USE_ESP32
|
|
7
|
+
|
|
8
|
+
#include "esphome/core/event_pool.h"
|
|
9
|
+
#include "esphome/core/lock_free_queue.h"
|
|
10
|
+
#include "espnow_packet.h"
|
|
11
|
+
|
|
12
|
+
#include <esp_idf_version.h>
|
|
13
|
+
|
|
14
|
+
#include <esp_mac.h>
|
|
15
|
+
#include <esp_now.h>
|
|
16
|
+
|
|
17
|
+
#include <array>
|
|
18
|
+
#include <map>
|
|
19
|
+
#include <memory>
|
|
20
|
+
#include <string>
|
|
21
|
+
#include <vector>
|
|
22
|
+
|
|
23
|
+
namespace esphome::espnow {
|
|
24
|
+
|
|
25
|
+
// Maximum size of the ESPNow event queue - must be power of 2 for lock-free queue
|
|
26
|
+
static constexpr size_t MAX_ESP_NOW_SEND_QUEUE_SIZE = 16;
|
|
27
|
+
static constexpr size_t MAX_ESP_NOW_RECEIVE_QUEUE_SIZE = 16;
|
|
28
|
+
|
|
29
|
+
using peer_address_t = std::array<uint8_t, ESP_NOW_ETH_ALEN>;
|
|
30
|
+
|
|
31
|
+
enum class ESPNowTriggers : uint8_t {
|
|
32
|
+
TRIGGER_NONE = 0,
|
|
33
|
+
ON_NEW_PEER = 1,
|
|
34
|
+
ON_RECEIVED = 2,
|
|
35
|
+
ON_BROADCASTED = 3,
|
|
36
|
+
ON_SUCCEED = 10,
|
|
37
|
+
ON_FAILED = 11,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
enum ESPNowState : uint8_t {
|
|
41
|
+
/** Nothing has been initialized yet. */
|
|
42
|
+
ESPNOW_STATE_OFF = 0,
|
|
43
|
+
/** ESPNOW is disabled. */
|
|
44
|
+
ESPNOW_STATE_DISABLED,
|
|
45
|
+
/** ESPNOW is enabled. */
|
|
46
|
+
ESPNOW_STATE_ENABLED,
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
struct ESPNowPeer {
|
|
50
|
+
uint8_t address[ESP_NOW_ETH_ALEN]; // MAC address of the peer
|
|
51
|
+
|
|
52
|
+
bool operator==(const ESPNowPeer &other) const { return memcmp(this->address, other.address, ESP_NOW_ETH_ALEN) == 0; }
|
|
53
|
+
bool operator==(const uint8_t *other) const { return memcmp(this->address, other, ESP_NOW_ETH_ALEN) == 0; }
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/// Handler interface for receiving ESPNow packets from unknown peers
|
|
57
|
+
/// Components should inherit from this class to handle incoming ESPNow data
|
|
58
|
+
class ESPNowUnknownPeerHandler {
|
|
59
|
+
public:
|
|
60
|
+
/// Called when an ESPNow packet is received from an unknown peer
|
|
61
|
+
/// @param info Information about the received packet (sender MAC, etc.)
|
|
62
|
+
/// @param data Pointer to the received data payload
|
|
63
|
+
/// @param size Size of the received data in bytes
|
|
64
|
+
/// @return true if the packet was handled, false otherwise
|
|
65
|
+
virtual bool on_unknown_peer(const ESPNowRecvInfo &info, const uint8_t *data, uint8_t size) = 0;
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
/// Handler interface for receiving ESPNow packets
|
|
69
|
+
/// Components should inherit from this class to handle incoming ESPNow data
|
|
70
|
+
class ESPNowReceivedPacketHandler {
|
|
71
|
+
public:
|
|
72
|
+
/// Called when an ESPNow packet is received
|
|
73
|
+
/// @param info Information about the received packet (sender MAC, etc.)
|
|
74
|
+
/// @param data Pointer to the received data payload
|
|
75
|
+
/// @param size Size of the received data in bytes
|
|
76
|
+
/// @return true if the packet was handled, false otherwise
|
|
77
|
+
virtual bool on_received(const ESPNowRecvInfo &info, const uint8_t *data, uint8_t size) = 0;
|
|
78
|
+
};
|
|
79
|
+
/// Handler interface for receiving broadcasted ESPNow packets
|
|
80
|
+
/// Components should inherit from this class to handle incoming ESPNow data
|
|
81
|
+
class ESPNowBroadcastedHandler {
|
|
82
|
+
public:
|
|
83
|
+
/// Called when a broadcasted ESPNow packet is received
|
|
84
|
+
/// @param info Information about the received packet (sender MAC, etc.)
|
|
85
|
+
/// @param data Pointer to the received data payload
|
|
86
|
+
/// @param size Size of the received data in bytes
|
|
87
|
+
/// @return true if the packet was handled, false otherwise
|
|
88
|
+
virtual bool on_broadcasted(const ESPNowRecvInfo &info, const uint8_t *data, uint8_t size) = 0;
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
class ESPNowComponent : public Component {
|
|
92
|
+
public:
|
|
93
|
+
ESPNowComponent();
|
|
94
|
+
void setup() override;
|
|
95
|
+
void loop() override;
|
|
96
|
+
void dump_config() override;
|
|
97
|
+
|
|
98
|
+
float get_setup_priority() const override { return setup_priority::LATE; }
|
|
99
|
+
|
|
100
|
+
// Add a peer to the internal list of peers
|
|
101
|
+
void add_peer(peer_address_t address) {
|
|
102
|
+
ESPNowPeer peer;
|
|
103
|
+
memcpy(peer.address, address.data(), ESP_NOW_ETH_ALEN);
|
|
104
|
+
this->peers_.push_back(peer);
|
|
105
|
+
}
|
|
106
|
+
// Add a peer with the esp_now api and add to the internal list if doesnt exist already
|
|
107
|
+
esp_err_t add_peer(const uint8_t *peer);
|
|
108
|
+
// Remove a peer with the esp_now api and remove from the internal list if exists
|
|
109
|
+
esp_err_t del_peer(const uint8_t *peer);
|
|
110
|
+
|
|
111
|
+
void set_wifi_channel(uint8_t channel) { this->wifi_channel_ = channel; }
|
|
112
|
+
void apply_wifi_channel();
|
|
113
|
+
uint8_t get_wifi_channel();
|
|
114
|
+
|
|
115
|
+
void set_auto_add_peer(bool value) { this->auto_add_peer_ = value; }
|
|
116
|
+
|
|
117
|
+
void enable();
|
|
118
|
+
void disable();
|
|
119
|
+
bool is_disabled() const { return this->state_ == ESPNOW_STATE_DISABLED; };
|
|
120
|
+
void set_enable_on_boot(bool enable_on_boot) { this->enable_on_boot_ = enable_on_boot; }
|
|
121
|
+
bool is_wifi_enabled();
|
|
122
|
+
|
|
123
|
+
/// @brief Queue a packet to be sent to a specific peer address.
|
|
124
|
+
/// This method will add the packet to the internal queue and
|
|
125
|
+
/// call the callback when the packet is sent.
|
|
126
|
+
/// Only one packet will be sent at any given time and the next one will not be sent until
|
|
127
|
+
/// the previous one has been acknowledged or failed.
|
|
128
|
+
/// @param peer_address MAC address of the peer to send the packet to
|
|
129
|
+
/// @param payload Data payload to send
|
|
130
|
+
/// @param callback Callback to call when the send operation is complete
|
|
131
|
+
/// @return ESP_OK on success, or an error code on failure
|
|
132
|
+
esp_err_t send(const uint8_t *peer_address, const std::vector<uint8_t> &payload,
|
|
133
|
+
const send_callback_t &callback = nullptr) {
|
|
134
|
+
return this->send(peer_address, payload.data(), payload.size(), callback);
|
|
135
|
+
}
|
|
136
|
+
esp_err_t send(const uint8_t *peer_address, const uint8_t *payload, size_t size,
|
|
137
|
+
const send_callback_t &callback = nullptr);
|
|
138
|
+
|
|
139
|
+
void register_received_handler(ESPNowReceivedPacketHandler *handler) { this->received_handlers_.push_back(handler); }
|
|
140
|
+
void register_unknown_peer_handler(ESPNowUnknownPeerHandler *handler) {
|
|
141
|
+
this->unknown_peer_handlers_.push_back(handler);
|
|
142
|
+
}
|
|
143
|
+
void register_broadcasted_handler(ESPNowBroadcastedHandler *handler) {
|
|
144
|
+
this->broadcasted_handlers_.push_back(handler);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
protected:
|
|
148
|
+
friend void on_data_received(const esp_now_recv_info_t *info, const uint8_t *data, int size);
|
|
149
|
+
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 5, 0)
|
|
150
|
+
friend void on_send_report(const esp_now_send_info_t *info, esp_now_send_status_t status);
|
|
151
|
+
#else
|
|
152
|
+
friend void on_send_report(const uint8_t *mac_addr, esp_now_send_status_t status);
|
|
153
|
+
#endif
|
|
154
|
+
|
|
155
|
+
void enable_();
|
|
156
|
+
void send_();
|
|
157
|
+
|
|
158
|
+
std::vector<ESPNowUnknownPeerHandler *> unknown_peer_handlers_;
|
|
159
|
+
std::vector<ESPNowReceivedPacketHandler *> received_handlers_;
|
|
160
|
+
std::vector<ESPNowBroadcastedHandler *> broadcasted_handlers_;
|
|
161
|
+
|
|
162
|
+
std::vector<ESPNowPeer> peers_{};
|
|
163
|
+
|
|
164
|
+
uint8_t own_address_[ESP_NOW_ETH_ALEN]{0};
|
|
165
|
+
LockFreeQueue<ESPNowPacket, MAX_ESP_NOW_RECEIVE_QUEUE_SIZE> receive_packet_queue_{};
|
|
166
|
+
EventPool<ESPNowPacket, MAX_ESP_NOW_RECEIVE_QUEUE_SIZE> receive_packet_pool_{};
|
|
167
|
+
|
|
168
|
+
LockFreeQueue<ESPNowSendPacket, MAX_ESP_NOW_SEND_QUEUE_SIZE> send_packet_queue_{};
|
|
169
|
+
EventPool<ESPNowSendPacket, MAX_ESP_NOW_SEND_QUEUE_SIZE> send_packet_pool_{};
|
|
170
|
+
ESPNowSendPacket *current_send_packet_{nullptr}; // Currently sending packet, nullptr if none
|
|
171
|
+
|
|
172
|
+
uint8_t wifi_channel_{0};
|
|
173
|
+
ESPNowState state_{ESPNOW_STATE_OFF};
|
|
174
|
+
|
|
175
|
+
bool auto_add_peer_{false};
|
|
176
|
+
bool enable_on_boot_{true};
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
extern ESPNowComponent *global_esp_now; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
|
180
|
+
|
|
181
|
+
} // namespace esphome::espnow
|
|
182
|
+
|
|
183
|
+
#endif // USE_ESP32
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#ifdef USE_ESP32
|
|
4
|
+
|
|
5
|
+
#include <esp_err.h>
|
|
6
|
+
#include <esp_now.h>
|
|
7
|
+
|
|
8
|
+
namespace esphome::espnow {
|
|
9
|
+
|
|
10
|
+
static const esp_err_t ESP_ERR_ESPNOW_CMP_BASE = (ESP_ERR_ESPNOW_BASE + 20);
|
|
11
|
+
static const esp_err_t ESP_ERR_ESPNOW_FAILED = (ESP_ERR_ESPNOW_CMP_BASE + 1);
|
|
12
|
+
static const esp_err_t ESP_ERR_ESPNOW_OWN_ADDRESS = (ESP_ERR_ESPNOW_CMP_BASE + 2);
|
|
13
|
+
static const esp_err_t ESP_ERR_ESPNOW_DATA_SIZE = (ESP_ERR_ESPNOW_CMP_BASE + 3);
|
|
14
|
+
static const esp_err_t ESP_ERR_ESPNOW_PEER_NOT_SET = (ESP_ERR_ESPNOW_CMP_BASE + 4);
|
|
15
|
+
static const esp_err_t ESP_ERR_ESPNOW_PEER_NOT_PAIRED = (ESP_ERR_ESPNOW_CMP_BASE + 5);
|
|
16
|
+
|
|
17
|
+
} // namespace esphome::espnow
|
|
18
|
+
|
|
19
|
+
#endif // USE_ESP32
|