esphome 2024.12.3__py3-none-any.whl → 2025.2.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 +16 -3
- esphome/components/adc/__init__.py +17 -11
- esphome/components/adc/adc_sensor.h +17 -0
- esphome/components/adc/adc_sensor_common.cpp +55 -0
- esphome/components/adc/adc_sensor_esp32.cpp +8 -5
- esphome/components/adc/adc_sensor_esp8266.cpp +10 -6
- esphome/components/adc/adc_sensor_libretiny.cpp +11 -6
- esphome/components/adc/adc_sensor_rp2040.cpp +13 -10
- esphome/components/adc/sensor.py +9 -3
- esphome/components/ads1115/ads1115.cpp +56 -7
- esphome/components/ads1115/ads1115.h +13 -1
- esphome/components/ads1115/sensor/__init__.py +16 -0
- esphome/components/ads1115/sensor/ads1115_sensor.cpp +2 -1
- esphome/components/ads1115/sensor/ads1115_sensor.h +2 -0
- esphome/components/animation/__init__.py +23 -261
- esphome/components/animation/animation.cpp +2 -2
- esphome/components/animation/animation.h +2 -1
- esphome/components/api/api_pb2.cpp +14 -0
- esphome/components/api/api_pb2.h +1 -0
- esphome/components/audio/__init__.py +112 -0
- esphome/components/audio/audio.cpp +67 -0
- esphome/components/audio/audio.h +125 -7
- esphome/components/audio/audio_decoder.cpp +361 -0
- esphome/components/audio/audio_decoder.h +135 -0
- esphome/components/audio/audio_reader.cpp +308 -0
- esphome/components/audio/audio_reader.h +85 -0
- esphome/components/audio/audio_resampler.cpp +159 -0
- esphome/components/audio/audio_resampler.h +101 -0
- esphome/components/audio/audio_transfer_buffer.cpp +165 -0
- esphome/components/audio/audio_transfer_buffer.h +139 -0
- esphome/components/audio_adc/__init__.py +41 -0
- esphome/components/audio_adc/audio_adc.h +17 -0
- esphome/components/audio_adc/automation.h +23 -0
- esphome/components/bk72xx/__init__.py +1 -0
- esphome/components/ble_client/ble_client.cpp +1 -2
- esphome/components/ble_client/sensor/__init__.py +1 -1
- esphome/components/ble_client/text_sensor/__init__.py +1 -1
- esphome/components/bluetooth_proxy/bluetooth_connection.cpp +5 -0
- esphome/components/bluetooth_proxy/bluetooth_connection.h +1 -0
- esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +5 -0
- esphome/components/ch422g/ch422g.h +2 -0
- esphome/components/climate/__init__.py +1 -1
- esphome/components/climate_ir/climate_ir.cpp +2 -1
- esphome/components/coolix/coolix.cpp +2 -1
- esphome/components/custom/__init__.py +0 -3
- esphome/components/custom/binary_sensor/__init__.py +2 -28
- esphome/components/custom/climate/__init__.py +2 -27
- esphome/components/custom/cover/__init__.py +2 -27
- esphome/components/custom/light/__init__.py +2 -27
- esphome/components/custom/output/__init__.py +2 -58
- esphome/components/custom/sensor/__init__.py +2 -24
- esphome/components/custom/switch/__init__.py +2 -24
- esphome/components/custom/text_sensor/__init__.py +2 -29
- esphome/components/custom_component/__init__.py +3 -27
- esphome/components/daly_bms/daly_bms.cpp +6 -0
- esphome/components/daly_bms/daly_bms.h +2 -0
- esphome/components/daly_bms/sensor.py +6 -0
- esphome/components/debug/debug_component.cpp +4 -0
- esphome/components/debug/debug_component.h +14 -0
- esphome/components/debug/debug_esp32.cpp +154 -74
- esphome/components/dfplayer/dfplayer.cpp +15 -2
- esphome/components/dfrobot_sen0395/dfrobot_sen0395.cpp +2 -1
- esphome/components/dht/dht.cpp +2 -1
- esphome/components/display/__init__.py +18 -5
- esphome/components/display/display.cpp +2 -1
- esphome/components/display/rect.cpp +2 -1
- esphome/components/es7210/__init__.py +0 -0
- esphome/components/es7210/audio_adc.py +51 -0
- esphome/components/es7210/es7210.cpp +228 -0
- esphome/components/es7210/es7210.h +62 -0
- esphome/components/es7210/es7210_const.h +129 -0
- esphome/components/es7243e/__init__.py +0 -0
- esphome/components/es7243e/audio_adc.py +34 -0
- esphome/components/es7243e/es7243e.cpp +125 -0
- esphome/components/es7243e/es7243e.h +37 -0
- esphome/components/es7243e/es7243e_const.h +54 -0
- esphome/components/es8156/__init__.py +0 -0
- esphome/components/es8156/audio_dac.py +27 -0
- esphome/components/es8156/es8156.cpp +87 -0
- esphome/components/es8156/es8156.h +51 -0
- esphome/components/es8156/es8156_const.h +68 -0
- esphome/components/es8311/audio_dac.py +1 -2
- esphome/components/esp32/__init__.py +1 -0
- esphome/components/esp32/core.cpp +5 -1
- esphome/components/esp32/gpio.h +2 -0
- esphome/components/esp32_ble/__init__.py +39 -0
- esphome/components/esp32_ble/queue.h +4 -4
- esphome/components/esp32_ble_client/ble_client_base.cpp +46 -0
- esphome/components/esp32_ble_client/ble_client_base.h +2 -0
- esphome/components/esp32_ble_server/__init__.py +582 -12
- esphome/components/esp32_ble_server/ble_characteristic.cpp +48 -60
- esphome/components/esp32_ble_server/ble_characteristic.h +24 -17
- esphome/components/esp32_ble_server/ble_descriptor.cpp +21 -9
- esphome/components/esp32_ble_server/ble_descriptor.h +17 -6
- esphome/components/esp32_ble_server/ble_server.cpp +62 -67
- esphome/components/esp32_ble_server/ble_server.h +28 -32
- esphome/components/esp32_ble_server/ble_server_automations.cpp +77 -0
- esphome/components/esp32_ble_server/ble_server_automations.h +115 -0
- esphome/components/esp32_ble_server/ble_service.cpp +17 -15
- esphome/components/esp32_ble_server/ble_service.h +10 -14
- esphome/components/esp32_ble_tracker/__init__.py +6 -39
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +33 -10
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +8 -4
- esphome/components/esp32_improv/__init__.py +2 -8
- esphome/components/esp32_improv/esp32_improv_component.cpp +21 -20
- esphome/components/esp32_improv/esp32_improv_component.h +3 -4
- esphome/components/esp32_rmt/__init__.py +28 -3
- esphome/components/esp32_rmt_led_strip/led_strip.cpp +73 -6
- esphome/components/esp32_rmt_led_strip/led_strip.h +21 -3
- esphome/components/esp32_rmt_led_strip/light.py +72 -7
- esphome/components/esp32_touch/esp32_touch.cpp +5 -0
- esphome/components/esp8266/__init__.py +1 -0
- esphome/components/esp8266/gpio.h +1 -0
- esphome/components/ethernet/__init__.py +10 -10
- esphome/components/event/event.cpp +4 -2
- esphome/components/event/event.h +2 -0
- esphome/components/event_emitter/__init__.py +5 -0
- esphome/components/event_emitter/event_emitter.cpp +14 -0
- esphome/components/event_emitter/event_emitter.h +63 -0
- esphome/components/gcja5/gcja5.cpp +2 -1
- esphome/components/haier/haier_base.cpp +2 -1
- esphome/components/haier/hon_climate.cpp +2 -1
- esphome/components/heatpumpir/heatpumpir.cpp +2 -1
- esphome/components/host/__init__.py +1 -0
- esphome/components/host/gpio.h +1 -0
- esphome/components/http_request/http_request.h +2 -2
- esphome/components/http_request/http_request_arduino.cpp +1 -1
- esphome/components/http_request/http_request_idf.cpp +1 -1
- esphome/components/i2c/i2c_bus_esp_idf.cpp +4 -0
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +7 -5
- esphome/components/i2s_audio/speaker/__init__.py +53 -6
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +92 -46
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +8 -0
- esphome/components/ili9xxx/display.py +29 -11
- esphome/components/ili9xxx/ili9xxx_display.cpp +2 -5
- esphome/components/ili9xxx/ili9xxx_display.h +2 -1
- esphome/components/image/__init__.py +443 -255
- esphome/components/image/image.cpp +115 -61
- esphome/components/image/image.h +15 -24
- esphome/components/json/json_util.cpp +8 -34
- esphome/components/libretiny/__init__.py +1 -0
- esphome/components/libretiny/gpio_arduino.h +1 -0
- esphome/components/light/light_color_values.h +1 -1
- esphome/components/logger/__init__.py +43 -7
- esphome/components/logger/logger.cpp +16 -11
- esphome/components/logger/logger.h +11 -7
- esphome/components/logger/select/__init__.py +29 -0
- esphome/components/logger/select/logger_level_select.cpp +27 -0
- esphome/components/logger/select/logger_level_select.h +15 -0
- esphome/components/lvgl/__init__.py +96 -73
- esphome/components/lvgl/automation.py +39 -7
- esphome/components/lvgl/defines.py +8 -2
- esphome/components/lvgl/lvgl_esphome.cpp +8 -15
- esphome/components/lvgl/lvgl_esphome.h +20 -5
- esphome/components/lvgl/schemas.py +25 -14
- esphome/components/lvgl/trigger.py +27 -3
- esphome/components/lvgl/widgets/dropdown.py +1 -1
- esphome/components/lvgl/widgets/keyboard.py +8 -1
- esphome/components/lvgl/widgets/meter.py +2 -1
- esphome/components/lvgl/widgets/msgbox.py +1 -1
- esphome/components/lvgl/widgets/obj.py +1 -12
- esphome/components/lvgl/widgets/page.py +37 -2
- esphome/components/lvgl/widgets/tabview.py +1 -1
- esphome/components/max6956/max6956.h +2 -0
- esphome/components/mcp23016/mcp23016.h +2 -0
- esphome/components/mcp23xxx_base/mcp23xxx_base.h +2 -0
- esphome/components/mdns/__init__.py +1 -1
- esphome/components/media_player/__init__.py +37 -8
- esphome/components/media_player/automation.h +11 -2
- esphome/components/media_player/media_player.cpp +8 -0
- esphome/components/media_player/media_player.h +8 -4
- esphome/components/micronova/switch/micronova_switch.cpp +4 -2
- esphome/components/midea/ac_automations.h +3 -1
- esphome/components/midea/air_conditioner.cpp +7 -5
- esphome/components/midea/air_conditioner.h +1 -1
- esphome/components/midea/climate.py +4 -2
- esphome/components/midea/ir_transmitter.h +36 -5
- esphome/components/mixer/__init__.py +0 -0
- esphome/components/mixer/speaker/__init__.py +172 -0
- esphome/components/mixer/speaker/automation.h +19 -0
- esphome/components/mixer/speaker/mixer_speaker.cpp +624 -0
- esphome/components/mixer/speaker/mixer_speaker.h +207 -0
- esphome/components/mpr121/mpr121.h +2 -0
- esphome/components/mqtt/__init__.py +1 -1
- esphome/components/mqtt/mqtt_client.cpp +7 -1
- esphome/components/mqtt/mqtt_client.h +1 -1
- esphome/components/mqtt/mqtt_climate.cpp +2 -2
- esphome/components/network/ip_address.h +2 -0
- esphome/components/nextion/automation.h +17 -0
- esphome/components/nextion/display.py +42 -17
- esphome/components/nextion/nextion.cpp +4 -10
- esphome/components/nextion/nextion.h +89 -82
- esphome/components/nextion/nextion_commands.cpp +10 -10
- esphome/components/ntc/sensor.py +2 -4
- esphome/components/online_image/__init__.py +98 -46
- esphome/components/online_image/bmp_image.cpp +101 -0
- esphome/components/online_image/bmp_image.h +40 -0
- esphome/components/online_image/image_decoder.cpp +28 -2
- esphome/components/online_image/image_decoder.h +24 -15
- esphome/components/online_image/jpeg_image.cpp +90 -0
- esphome/components/online_image/jpeg_image.h +34 -0
- esphome/components/online_image/online_image.cpp +112 -53
- esphome/components/online_image/online_image.h +24 -7
- esphome/components/online_image/png_image.cpp +7 -3
- esphome/components/online_image/png_image.h +2 -1
- esphome/components/opentherm/__init__.py +73 -7
- esphome/components/opentherm/automation.h +25 -0
- esphome/components/opentherm/const.py +1 -0
- esphome/components/opentherm/generate.py +39 -6
- esphome/components/opentherm/hub.cpp +117 -79
- esphome/components/opentherm/hub.h +31 -15
- esphome/components/opentherm/opentherm.cpp +47 -23
- esphome/components/opentherm/opentherm.h +27 -6
- esphome/components/opentherm/opentherm_macros.h +11 -0
- esphome/components/opentherm/schema.py +78 -1
- esphome/components/opentherm/validate.py +7 -2
- esphome/components/pca6416a/pca6416a.h +2 -0
- esphome/components/pca9554/pca9554.h +2 -0
- esphome/components/pcf8574/pcf8574.h +2 -0
- esphome/components/preferences/__init__.py +2 -4
- esphome/components/preferences/syncer.h +10 -3
- esphome/components/prometheus/prometheus_handler.cpp +313 -0
- esphome/components/prometheus/prometheus_handler.h +48 -7
- esphome/components/psram/psram.cpp +8 -1
- esphome/components/pulse_counter/pulse_counter_sensor.cpp +14 -9
- esphome/components/pulse_counter/pulse_counter_sensor.h +4 -4
- esphome/components/pulse_meter/pulse_meter_sensor.cpp +2 -0
- esphome/components/qspi_dbi/__init__.py +3 -0
- esphome/components/qspi_dbi/display.py +74 -47
- esphome/components/qspi_dbi/models.py +245 -2
- esphome/components/qspi_dbi/qspi_dbi.cpp +9 -16
- esphome/components/qspi_dbi/qspi_dbi.h +2 -2
- esphome/components/remote_base/__init__.py +77 -25
- esphome/components/remote_base/remote_base.cpp +1 -1
- esphome/components/remote_base/remote_base.h +20 -2
- esphome/components/remote_base/toto_protocol.cpp +100 -0
- esphome/components/remote_base/toto_protocol.h +45 -0
- esphome/components/remote_receiver/__init__.py +55 -10
- esphome/components/remote_receiver/remote_receiver.h +36 -3
- esphome/components/remote_receiver/remote_receiver_esp32.cpp +145 -6
- esphome/components/remote_transmitter/__init__.py +62 -4
- esphome/components/remote_transmitter/remote_transmitter.h +21 -2
- esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +140 -4
- esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +3 -3
- esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +3 -3
- esphome/components/resampler/__init__.py +0 -0
- esphome/components/resampler/speaker/__init__.py +103 -0
- esphome/components/resampler/speaker/resampler_speaker.cpp +318 -0
- esphome/components/resampler/speaker/resampler_speaker.h +107 -0
- esphome/components/resistance/resistance_sensor.h +2 -3
- esphome/components/resistance/sensor.py +2 -9
- esphome/components/rotary_encoder/rotary_encoder.cpp +8 -4
- esphome/components/rp2040/__init__.py +1 -0
- esphome/components/rp2040/gpio.h +1 -0
- esphome/components/rtl87xx/__init__.py +2 -0
- esphome/components/sdl/binary_sensor.py +270 -0
- esphome/components/sdl/sdl_esphome.cpp +16 -0
- esphome/components/sdl/sdl_esphome.h +9 -0
- esphome/components/seeed_mr60bha2/binary_sensor.py +25 -0
- esphome/components/seeed_mr60bha2/seeed_mr60bha2.cpp +26 -2
- esphome/components/seeed_mr60bha2/seeed_mr60bha2.h +9 -20
- esphome/components/seeed_mr60bha2/sensor.py +9 -1
- esphome/components/sn74hc165/sn74hc165.h +3 -0
- esphome/components/sn74hc595/sn74hc595.h +3 -0
- esphome/components/speaker/__init__.py +5 -4
- esphome/components/speaker/media_player/__init__.py +458 -0
- esphome/components/speaker/media_player/audio_pipeline.cpp +568 -0
- esphome/components/speaker/media_player/audio_pipeline.h +159 -0
- esphome/components/speaker/media_player/automation.h +26 -0
- esphome/components/speaker/media_player/speaker_media_player.cpp +577 -0
- esphome/components/speaker/media_player/speaker_media_player.h +160 -0
- esphome/components/speaker/speaker.h +20 -0
- esphome/components/spi/__init__.py +1 -5
- esphome/components/spi/spi.cpp +7 -1
- esphome/components/spi/spi.h +21 -2
- esphome/components/spi_led_strip/light.py +3 -5
- esphome/components/spi_led_strip/spi_led_strip.cpp +67 -0
- esphome/components/spi_led_strip/spi_led_strip.h +8 -60
- esphome/components/sprinkler/sprinkler.cpp +3 -1
- esphome/components/sx1509/sx1509_gpio_pin.h +2 -0
- esphome/components/tca9555/tca9555.h +2 -0
- esphome/components/toshiba/toshiba.cpp +2 -1
- esphome/components/tuya/light/tuya_light.cpp +4 -2
- esphome/components/uart/uart_component_esp32_arduino.cpp +2 -2
- esphome/components/uart/uart_component_esp_idf.cpp +2 -2
- esphome/components/udp/__init__.py +8 -2
- esphome/components/udp/udp_component.cpp +25 -56
- esphome/components/udp/udp_component.h +3 -0
- esphome/components/uponor_smatrix/sensor/__init__.py +14 -4
- esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.cpp +5 -0
- esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.h +1 -0
- esphome/components/uptime/text_sensor/__init__.py +19 -0
- esphome/components/uptime/text_sensor/uptime_text_sensor.cpp +63 -0
- esphome/components/uptime/text_sensor/uptime_text_sensor.h +25 -0
- esphome/components/voice_assistant/voice_assistant.cpp +24 -14
- esphome/components/voice_assistant/voice_assistant.h +8 -0
- esphome/components/waveshare_epaper/display.py +22 -1
- esphome/components/waveshare_epaper/waveshare_213v3.cpp +9 -3
- esphome/components/waveshare_epaper/waveshare_epaper.cpp +1155 -44
- esphome/components/waveshare_epaper/waveshare_epaper.h +208 -7
- esphome/components/web_server/web_server.cpp +28 -6
- esphome/components/weikai/weikai.h +2 -0
- esphome/components/wifi/__init__.py +6 -6
- esphome/components/wifi/wifi_component.cpp +1 -1
- esphome/components/wifi/wifi_component_esp32_arduino.cpp +30 -1
- esphome/components/wireguard/__init__.py +2 -2
- esphome/components/xl9535/xl9535.h +2 -0
- esphome/components/xxtea/__init__.py +3 -0
- esphome/components/xxtea/xxtea.cpp +46 -0
- esphome/components/xxtea/xxtea.h +26 -0
- esphome/components/yashima/yashima.cpp +2 -1
- esphome/config.py +9 -5
- esphome/config_validation.py +55 -17
- esphome/const.py +7 -10
- esphome/core/__init__.py +6 -13
- esphome/core/base_automation.h +1 -0
- esphome/core/config.py +57 -72
- esphome/core/defines.h +9 -1
- esphome/core/gpio.h +7 -0
- esphome/core/helpers.cpp +19 -15
- esphome/core/helpers.h +57 -8
- esphome/core/log.h +9 -7
- esphome/cpp_generator.py +2 -2
- esphome/espota2.py +3 -2
- esphome/loader.py +12 -4
- esphome/log.py +5 -7
- esphome/yaml_util.py +2 -2
- {esphome-2024.12.3.dist-info → esphome-2025.2.0b1.dist-info}/METADATA +12 -7
- {esphome-2024.12.3.dist-info → esphome-2025.2.0b1.dist-info}/RECORD +338 -289
- esphome/components/custom/binary_sensor/custom_binary_sensor.cpp +0 -16
- esphome/components/custom/binary_sensor/custom_binary_sensor.h +0 -26
- esphome/components/custom/climate/custom_climate.h +0 -22
- esphome/components/custom/cover/custom_cover.h +0 -21
- esphome/components/custom/light/custom_light_output.h +0 -24
- esphome/components/custom/output/custom_output.h +0 -37
- esphome/components/custom/sensor/custom_sensor.cpp +0 -16
- esphome/components/custom/sensor/custom_sensor.h +0 -24
- esphome/components/custom/switch/custom_switch.cpp +0 -16
- esphome/components/custom/switch/custom_switch.h +0 -24
- esphome/components/custom/text_sensor/custom_text_sensor.cpp +0 -16
- esphome/components/custom/text_sensor/custom_text_sensor.h +0 -26
- esphome/components/custom_component/custom_component.h +0 -28
- esphome/components/esp32_ble_server/ble_2901.cpp +0 -18
- esphome/components/esp32_ble_server/ble_2901.h +0 -19
- esphome/components/resistance_sampler/__init__.py +0 -6
- esphome/components/resistance_sampler/resistance_sampler.h +0 -10
- esphome/components/uptime/{sensor.py → sensor/__init__.py} +3 -3
- /esphome/components/uptime/{uptime_seconds_sensor.cpp → sensor/uptime_seconds_sensor.cpp} +0 -0
- /esphome/components/uptime/{uptime_seconds_sensor.h → sensor/uptime_seconds_sensor.h} +0 -0
- /esphome/components/uptime/{uptime_timestamp_sensor.cpp → sensor/uptime_timestamp_sensor.cpp} +0 -0
- /esphome/components/uptime/{uptime_timestamp_sensor.h → sensor/uptime_timestamp_sensor.h} +0 -0
- {esphome-2024.12.3.dist-info → esphome-2025.2.0b1.dist-info}/LICENSE +0 -0
- {esphome-2024.12.3.dist-info → esphome-2025.2.0b1.dist-info}/WHEEL +0 -0
- {esphome-2024.12.3.dist-info → esphome-2025.2.0b1.dist-info}/entry_points.txt +0 -0
- {esphome-2024.12.3.dist-info → esphome-2025.2.0b1.dist-info}/top_level.txt +0 -0
@@ -32,70 +32,36 @@ BLECharacteristic::BLECharacteristic(const ESPBTUUID uuid, uint32_t properties)
|
|
32
32
|
this->set_write_no_response_property((properties & PROPERTY_WRITE_NR) != 0);
|
33
33
|
}
|
34
34
|
|
35
|
-
void BLECharacteristic::set_value(
|
35
|
+
void BLECharacteristic::set_value(ByteBuffer buffer) { this->set_value(buffer.get_data()); }
|
36
|
+
|
37
|
+
void BLECharacteristic::set_value(const std::vector<uint8_t> &buffer) {
|
36
38
|
xSemaphoreTake(this->set_value_lock_, 0L);
|
37
|
-
this->value_ =
|
39
|
+
this->value_ = buffer;
|
38
40
|
xSemaphoreGive(this->set_value_lock_);
|
39
41
|
}
|
40
|
-
void BLECharacteristic::set_value(const std::string &
|
41
|
-
this->set_value(std::vector<uint8_t>(
|
42
|
-
}
|
43
|
-
void BLECharacteristic::set_value(const uint8_t *data, size_t length) {
|
44
|
-
this->set_value(std::vector<uint8_t>(data, data + length));
|
45
|
-
}
|
46
|
-
void BLECharacteristic::set_value(uint8_t &data) {
|
47
|
-
uint8_t temp[1];
|
48
|
-
temp[0] = data;
|
49
|
-
this->set_value(temp, 1);
|
50
|
-
}
|
51
|
-
void BLECharacteristic::set_value(uint16_t &data) {
|
52
|
-
uint8_t temp[2];
|
53
|
-
temp[0] = data;
|
54
|
-
temp[1] = data >> 8;
|
55
|
-
this->set_value(temp, 2);
|
56
|
-
}
|
57
|
-
void BLECharacteristic::set_value(uint32_t &data) {
|
58
|
-
uint8_t temp[4];
|
59
|
-
temp[0] = data;
|
60
|
-
temp[1] = data >> 8;
|
61
|
-
temp[2] = data >> 16;
|
62
|
-
temp[3] = data >> 24;
|
63
|
-
this->set_value(temp, 4);
|
64
|
-
}
|
65
|
-
void BLECharacteristic::set_value(int &data) {
|
66
|
-
uint8_t temp[4];
|
67
|
-
temp[0] = data;
|
68
|
-
temp[1] = data >> 8;
|
69
|
-
temp[2] = data >> 16;
|
70
|
-
temp[3] = data >> 24;
|
71
|
-
this->set_value(temp, 4);
|
72
|
-
}
|
73
|
-
void BLECharacteristic::set_value(float &data) {
|
74
|
-
float temp = data;
|
75
|
-
this->set_value((uint8_t *) &temp, 4);
|
76
|
-
}
|
77
|
-
void BLECharacteristic::set_value(double &data) {
|
78
|
-
double temp = data;
|
79
|
-
this->set_value((uint8_t *) &temp, 8);
|
80
|
-
}
|
81
|
-
void BLECharacteristic::set_value(bool &data) {
|
82
|
-
uint8_t temp[1];
|
83
|
-
temp[0] = data;
|
84
|
-
this->set_value(temp, 1);
|
42
|
+
void BLECharacteristic::set_value(const std::string &buffer) {
|
43
|
+
this->set_value(std::vector<uint8_t>(buffer.begin(), buffer.end()));
|
85
44
|
}
|
86
45
|
|
87
|
-
void BLECharacteristic::notify(
|
88
|
-
if (
|
89
|
-
|
90
|
-
// TODO: Handle when notification=false
|
91
|
-
}
|
92
|
-
if (this->service_->get_server()->get_connected_client_count() == 0)
|
46
|
+
void BLECharacteristic::notify() {
|
47
|
+
if (this->service_ == nullptr || this->service_->get_server() == nullptr ||
|
48
|
+
this->service_->get_server()->get_connected_client_count() == 0)
|
93
49
|
return;
|
94
50
|
|
95
51
|
for (auto &client : this->service_->get_server()->get_clients()) {
|
96
52
|
size_t length = this->value_.size();
|
97
|
-
|
98
|
-
|
53
|
+
// If the client is not in the list of clients to notify, skip it
|
54
|
+
if (this->clients_to_notify_.count(client) == 0)
|
55
|
+
continue;
|
56
|
+
// If the client is in the list of clients to notify, check if it requires an ack (i.e. INDICATE)
|
57
|
+
bool require_ack = this->clients_to_notify_[client];
|
58
|
+
// TODO: Remove this block when INDICATE acknowledgment is supported
|
59
|
+
if (require_ack) {
|
60
|
+
ESP_LOGW(TAG, "INDICATE acknowledgment is not yet supported (i.e. it works as a NOTIFY)");
|
61
|
+
require_ack = false;
|
62
|
+
}
|
63
|
+
esp_err_t err = esp_ble_gatts_send_indicate(this->service_->get_server()->get_gatts_if(), client, this->handle_,
|
64
|
+
length, this->value_.data(), require_ack);
|
99
65
|
if (err != ESP_OK) {
|
100
66
|
ESP_LOGE(TAG, "esp_ble_gatts_send_indicate failed %d", err);
|
101
67
|
return;
|
@@ -103,7 +69,24 @@ void BLECharacteristic::notify(bool notification) {
|
|
103
69
|
}
|
104
70
|
}
|
105
71
|
|
106
|
-
void BLECharacteristic::add_descriptor(BLEDescriptor *descriptor) {
|
72
|
+
void BLECharacteristic::add_descriptor(BLEDescriptor *descriptor) {
|
73
|
+
// If the descriptor is the CCCD descriptor, listen to its write event to know if the client wants to be notified
|
74
|
+
if (descriptor->get_uuid() == ESPBTUUID::from_uint16(ESP_GATT_UUID_CHAR_CLIENT_CONFIG)) {
|
75
|
+
descriptor->on(BLEDescriptorEvt::VectorEvt::ON_WRITE, [this](const std::vector<uint8_t> &value, uint16_t conn_id) {
|
76
|
+
if (value.size() != 2)
|
77
|
+
return;
|
78
|
+
uint16_t cccd = encode_uint16(value[1], value[0]);
|
79
|
+
bool notify = (cccd & 1) != 0;
|
80
|
+
bool indicate = (cccd & 2) != 0;
|
81
|
+
if (notify || indicate) {
|
82
|
+
this->clients_to_notify_[conn_id] = indicate;
|
83
|
+
} else {
|
84
|
+
this->clients_to_notify_.erase(conn_id);
|
85
|
+
}
|
86
|
+
});
|
87
|
+
}
|
88
|
+
this->descriptors_.push_back(descriptor);
|
89
|
+
}
|
107
90
|
|
108
91
|
void BLECharacteristic::remove_descriptor(BLEDescriptor *descriptor) {
|
109
92
|
this->descriptors_.erase(std::remove(this->descriptors_.begin(), this->descriptors_.end(), descriptor),
|
@@ -223,6 +206,9 @@ void BLECharacteristic::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt
|
|
223
206
|
if (!param->read.need_rsp)
|
224
207
|
break; // For some reason you can request a read but not want a response
|
225
208
|
|
209
|
+
this->EventEmitter<BLECharacteristicEvt::EmptyEvt, uint16_t>::emit_(BLECharacteristicEvt::EmptyEvt::ON_READ,
|
210
|
+
param->read.conn_id);
|
211
|
+
|
226
212
|
uint16_t max_offset = 22;
|
227
213
|
|
228
214
|
esp_gatt_rsp_t response;
|
@@ -262,13 +248,13 @@ void BLECharacteristic::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt
|
|
262
248
|
}
|
263
249
|
case ESP_GATTS_WRITE_EVT: {
|
264
250
|
if (this->handle_ != param->write.handle)
|
265
|
-
|
251
|
+
break;
|
266
252
|
|
267
253
|
if (param->write.is_prep) {
|
268
254
|
this->value_.insert(this->value_.end(), param->write.value, param->write.value + param->write.len);
|
269
255
|
this->write_event_ = true;
|
270
256
|
} else {
|
271
|
-
this->set_value(param->write.value, param->write.len);
|
257
|
+
this->set_value(ByteBuffer::wrap(param->write.value, param->write.len));
|
272
258
|
}
|
273
259
|
|
274
260
|
if (param->write.need_rsp) {
|
@@ -289,7 +275,8 @@ void BLECharacteristic::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt
|
|
289
275
|
}
|
290
276
|
|
291
277
|
if (!param->write.is_prep) {
|
292
|
-
this->
|
278
|
+
this->EventEmitter<BLECharacteristicEvt::VectorEvt, std::vector<uint8_t>, uint16_t>::emit_(
|
279
|
+
BLECharacteristicEvt::VectorEvt::ON_WRITE, this->value_, param->write.conn_id);
|
293
280
|
}
|
294
281
|
|
295
282
|
break;
|
@@ -300,7 +287,8 @@ void BLECharacteristic::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt
|
|
300
287
|
break;
|
301
288
|
this->write_event_ = false;
|
302
289
|
if (param->exec_write.exec_write_flag == ESP_GATT_PREP_WRITE_EXEC) {
|
303
|
-
this->
|
290
|
+
this->EventEmitter<BLECharacteristicEvt::VectorEvt, std::vector<uint8_t>, uint16_t>::emit_(
|
291
|
+
BLECharacteristicEvt::VectorEvt::ON_WRITE, this->value_, param->exec_write.conn_id);
|
304
292
|
}
|
305
293
|
esp_err_t err =
|
306
294
|
esp_ble_gatts_send_response(gatts_if, param->write.conn_id, param->write.trans_id, ESP_GATT_OK, nullptr);
|
@@ -2,8 +2,11 @@
|
|
2
2
|
|
3
3
|
#include "ble_descriptor.h"
|
4
4
|
#include "esphome/components/esp32_ble/ble_uuid.h"
|
5
|
+
#include "esphome/components/event_emitter/event_emitter.h"
|
6
|
+
#include "esphome/components/bytebuffer/bytebuffer.h"
|
5
7
|
|
6
8
|
#include <vector>
|
9
|
+
#include <unordered_map>
|
7
10
|
|
8
11
|
#ifdef USE_ESP32
|
9
12
|
|
@@ -19,24 +22,30 @@ namespace esphome {
|
|
19
22
|
namespace esp32_ble_server {
|
20
23
|
|
21
24
|
using namespace esp32_ble;
|
25
|
+
using namespace bytebuffer;
|
26
|
+
using namespace event_emitter;
|
22
27
|
|
23
28
|
class BLEService;
|
24
29
|
|
25
|
-
|
30
|
+
namespace BLECharacteristicEvt {
|
31
|
+
enum VectorEvt {
|
32
|
+
ON_WRITE,
|
33
|
+
};
|
34
|
+
|
35
|
+
enum EmptyEvt {
|
36
|
+
ON_READ,
|
37
|
+
};
|
38
|
+
} // namespace BLECharacteristicEvt
|
39
|
+
|
40
|
+
class BLECharacteristic : public EventEmitter<BLECharacteristicEvt::VectorEvt, std::vector<uint8_t>, uint16_t>,
|
41
|
+
public EventEmitter<BLECharacteristicEvt::EmptyEvt, uint16_t> {
|
26
42
|
public:
|
27
43
|
BLECharacteristic(ESPBTUUID uuid, uint32_t properties);
|
28
44
|
~BLECharacteristic();
|
29
45
|
|
30
|
-
void set_value(
|
31
|
-
void set_value(std::vector<uint8_t>
|
32
|
-
void set_value(const std::string &
|
33
|
-
void set_value(uint8_t &data);
|
34
|
-
void set_value(uint16_t &data);
|
35
|
-
void set_value(uint32_t &data);
|
36
|
-
void set_value(int &data);
|
37
|
-
void set_value(float &data);
|
38
|
-
void set_value(double &data);
|
39
|
-
void set_value(bool &data);
|
46
|
+
void set_value(ByteBuffer buffer);
|
47
|
+
void set_value(const std::vector<uint8_t> &buffer);
|
48
|
+
void set_value(const std::string &buffer);
|
40
49
|
|
41
50
|
void set_broadcast_property(bool value);
|
42
51
|
void set_indicate_property(bool value);
|
@@ -45,13 +54,12 @@ class BLECharacteristic {
|
|
45
54
|
void set_write_property(bool value);
|
46
55
|
void set_write_no_response_property(bool value);
|
47
56
|
|
48
|
-
void notify(
|
57
|
+
void notify();
|
49
58
|
|
50
59
|
void do_create(BLEService *service);
|
60
|
+
void do_delete() { this->clients_to_notify_.clear(); }
|
51
61
|
void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);
|
52
62
|
|
53
|
-
void on_write(const std::function<void(const std::vector<uint8_t> &)> &&func) { this->on_write_ = func; }
|
54
|
-
|
55
63
|
void add_descriptor(BLEDescriptor *descriptor);
|
56
64
|
void remove_descriptor(BLEDescriptor *descriptor);
|
57
65
|
|
@@ -71,7 +79,7 @@ class BLECharacteristic {
|
|
71
79
|
|
72
80
|
protected:
|
73
81
|
bool write_event_{false};
|
74
|
-
BLEService *service_;
|
82
|
+
BLEService *service_{};
|
75
83
|
ESPBTUUID uuid_;
|
76
84
|
esp_gatt_char_prop_t properties_;
|
77
85
|
uint16_t handle_{0xFFFF};
|
@@ -81,8 +89,7 @@ class BLECharacteristic {
|
|
81
89
|
SemaphoreHandle_t set_value_lock_;
|
82
90
|
|
83
91
|
std::vector<BLEDescriptor *> descriptors_;
|
84
|
-
|
85
|
-
std::function<void(const std::vector<uint8_t> &)> on_write_;
|
92
|
+
std::unordered_map<uint16_t, bool> clients_to_notify_;
|
86
93
|
|
87
94
|
esp_gatt_perm_t permissions_ = ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE;
|
88
95
|
|
@@ -12,11 +12,19 @@ namespace esp32_ble_server {
|
|
12
12
|
|
13
13
|
static const char *const TAG = "esp32_ble_server.descriptor";
|
14
14
|
|
15
|
-
|
15
|
+
static RAMAllocator<uint8_t> descriptor_allocator{}; // NOLINT
|
16
|
+
|
17
|
+
BLEDescriptor::BLEDescriptor(ESPBTUUID uuid, uint16_t max_len, bool read, bool write) {
|
16
18
|
this->uuid_ = uuid;
|
17
19
|
this->value_.attr_len = 0;
|
18
20
|
this->value_.attr_max_len = max_len;
|
19
|
-
this->value_.attr_value = (
|
21
|
+
this->value_.attr_value = descriptor_allocator.allocate(max_len);
|
22
|
+
if (read) {
|
23
|
+
this->permissions_ |= ESP_GATT_PERM_READ;
|
24
|
+
}
|
25
|
+
if (write) {
|
26
|
+
this->permissions_ |= ESP_GATT_PERM_WRITE;
|
27
|
+
}
|
20
28
|
}
|
21
29
|
|
22
30
|
BLEDescriptor::~BLEDescriptor() { free(this->value_.attr_value); } // NOLINT
|
@@ -38,14 +46,15 @@ void BLEDescriptor::do_create(BLECharacteristic *characteristic) {
|
|
38
46
|
this->state_ = CREATING;
|
39
47
|
}
|
40
48
|
|
41
|
-
void BLEDescriptor::set_value(
|
42
|
-
|
49
|
+
void BLEDescriptor::set_value(std::vector<uint8_t> buffer) {
|
50
|
+
size_t length = buffer.size();
|
51
|
+
|
43
52
|
if (length > this->value_.attr_max_len) {
|
44
53
|
ESP_LOGE(TAG, "Size %d too large, must be no bigger than %d", length, this->value_.attr_max_len);
|
45
54
|
return;
|
46
55
|
}
|
47
56
|
this->value_.attr_len = length;
|
48
|
-
memcpy(this->value_.attr_value, data, length);
|
57
|
+
memcpy(this->value_.attr_value, buffer.data(), length);
|
49
58
|
}
|
50
59
|
|
51
60
|
void BLEDescriptor::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
|
@@ -61,10 +70,13 @@ void BLEDescriptor::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_
|
|
61
70
|
break;
|
62
71
|
}
|
63
72
|
case ESP_GATTS_WRITE_EVT: {
|
64
|
-
if (this->handle_
|
65
|
-
|
66
|
-
|
67
|
-
|
73
|
+
if (this->handle_ != param->write.handle)
|
74
|
+
break;
|
75
|
+
this->value_.attr_len = param->write.len;
|
76
|
+
memcpy(this->value_.attr_value, param->write.value, param->write.len);
|
77
|
+
this->emit_(BLEDescriptorEvt::VectorEvt::ON_WRITE,
|
78
|
+
std::vector<uint8_t>(param->write.value, param->write.value + param->write.len),
|
79
|
+
param->write.conn_id);
|
68
80
|
break;
|
69
81
|
}
|
70
82
|
default:
|
@@ -1,6 +1,8 @@
|
|
1
1
|
#pragma once
|
2
2
|
|
3
3
|
#include "esphome/components/esp32_ble/ble_uuid.h"
|
4
|
+
#include "esphome/components/event_emitter/event_emitter.h"
|
5
|
+
#include "esphome/components/bytebuffer/bytebuffer.h"
|
4
6
|
|
5
7
|
#ifdef USE_ESP32
|
6
8
|
|
@@ -11,17 +13,26 @@ namespace esphome {
|
|
11
13
|
namespace esp32_ble_server {
|
12
14
|
|
13
15
|
using namespace esp32_ble;
|
16
|
+
using namespace bytebuffer;
|
17
|
+
using namespace event_emitter;
|
14
18
|
|
15
19
|
class BLECharacteristic;
|
16
20
|
|
17
|
-
|
21
|
+
namespace BLEDescriptorEvt {
|
22
|
+
enum VectorEvt {
|
23
|
+
ON_WRITE,
|
24
|
+
};
|
25
|
+
} // namespace BLEDescriptorEvt
|
26
|
+
|
27
|
+
class BLEDescriptor : public EventEmitter<BLEDescriptorEvt::VectorEvt, std::vector<uint8_t>, uint16_t> {
|
18
28
|
public:
|
19
|
-
BLEDescriptor(ESPBTUUID uuid, uint16_t max_len = 100);
|
29
|
+
BLEDescriptor(ESPBTUUID uuid, uint16_t max_len = 100, bool read = true, bool write = true);
|
20
30
|
virtual ~BLEDescriptor();
|
21
31
|
void do_create(BLECharacteristic *characteristic);
|
32
|
+
ESPBTUUID get_uuid() const { return this->uuid_; }
|
22
33
|
|
23
|
-
void set_value(
|
24
|
-
void set_value(
|
34
|
+
void set_value(std::vector<uint8_t> buffer);
|
35
|
+
void set_value(ByteBuffer buffer) { this->set_value(buffer.get_data()); }
|
25
36
|
|
26
37
|
void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t *param);
|
27
38
|
|
@@ -33,9 +44,9 @@ class BLEDescriptor {
|
|
33
44
|
ESPBTUUID uuid_;
|
34
45
|
uint16_t handle_{0xFFFF};
|
35
46
|
|
36
|
-
esp_attr_value_t value_;
|
47
|
+
esp_attr_value_t value_{};
|
37
48
|
|
38
|
-
esp_gatt_perm_t permissions_
|
49
|
+
esp_gatt_perm_t permissions_{};
|
39
50
|
|
40
51
|
enum State : uint8_t {
|
41
52
|
FAILED = 0x00,
|
@@ -19,11 +19,6 @@ namespace esp32_ble_server {
|
|
19
19
|
|
20
20
|
static const char *const TAG = "esp32_ble_server";
|
21
21
|
|
22
|
-
static const uint16_t DEVICE_INFORMATION_SERVICE_UUID = 0x180A;
|
23
|
-
static const uint16_t MODEL_UUID = 0x2A24;
|
24
|
-
static const uint16_t VERSION_UUID = 0x2A26;
|
25
|
-
static const uint16_t MANUFACTURER_UUID = 0x2A29;
|
26
|
-
|
27
22
|
void BLEServer::setup() {
|
28
23
|
if (this->parent_->is_failed()) {
|
29
24
|
this->mark_failed();
|
@@ -38,9 +33,27 @@ void BLEServer::loop() {
|
|
38
33
|
return;
|
39
34
|
}
|
40
35
|
switch (this->state_) {
|
41
|
-
case RUNNING:
|
42
|
-
|
43
|
-
|
36
|
+
case RUNNING: {
|
37
|
+
// Start all services that are pending to start
|
38
|
+
if (!this->services_to_start_.empty()) {
|
39
|
+
uint16_t index_to_remove = 0;
|
40
|
+
// Iterate over the services to start
|
41
|
+
for (unsigned i = 0; i < this->services_to_start_.size(); i++) {
|
42
|
+
BLEService *service = this->services_to_start_[i];
|
43
|
+
if (service->is_created()) {
|
44
|
+
service->start(); // Needs to be called once per characteristic in the service
|
45
|
+
} else {
|
46
|
+
index_to_remove = i + 1;
|
47
|
+
}
|
48
|
+
}
|
49
|
+
// Remove the services that have been started
|
50
|
+
if (index_to_remove > 0) {
|
51
|
+
this->services_to_start_.erase(this->services_to_start_.begin(),
|
52
|
+
this->services_to_start_.begin() + index_to_remove - 1);
|
53
|
+
}
|
54
|
+
}
|
55
|
+
break;
|
56
|
+
}
|
44
57
|
case INIT: {
|
45
58
|
esp_err_t err = esp_ble_gatts_app_register(0);
|
46
59
|
if (err != ESP_OK) {
|
@@ -53,29 +66,26 @@ void BLEServer::loop() {
|
|
53
66
|
}
|
54
67
|
case REGISTERING: {
|
55
68
|
if (this->registered_) {
|
69
|
+
// Create the device information service first so
|
70
|
+
// it is at the top of the GATT table
|
71
|
+
this->device_information_service_->do_create(this);
|
56
72
|
// Create all services previously created
|
57
73
|
for (auto &pair : this->services_) {
|
74
|
+
if (pair.second == this->device_information_service_) {
|
75
|
+
continue;
|
76
|
+
}
|
58
77
|
pair.second->do_create(this);
|
59
78
|
}
|
60
|
-
if (this->device_information_service_ == nullptr) {
|
61
|
-
this->create_service(ESPBTUUID::from_uint16(DEVICE_INFORMATION_SERVICE_UUID));
|
62
|
-
this->device_information_service_ =
|
63
|
-
this->get_service(ESPBTUUID::from_uint16(DEVICE_INFORMATION_SERVICE_UUID));
|
64
|
-
this->create_device_characteristics_();
|
65
|
-
}
|
66
79
|
this->state_ = STARTING_SERVICE;
|
67
80
|
}
|
68
81
|
break;
|
69
82
|
}
|
70
83
|
case STARTING_SERVICE: {
|
71
|
-
if (!this->device_information_service_->is_created()) {
|
72
|
-
break;
|
73
|
-
}
|
74
84
|
if (this->device_information_service_->is_running()) {
|
75
85
|
this->state_ = RUNNING;
|
76
86
|
this->restart_advertising_();
|
77
87
|
ESP_LOGD(TAG, "BLE server setup successfully");
|
78
|
-
} else if (
|
88
|
+
} else if (this->device_information_service_->is_created()) {
|
79
89
|
this->device_information_service_->start();
|
80
90
|
}
|
81
91
|
break;
|
@@ -93,81 +103,66 @@ void BLEServer::restart_advertising_() {
|
|
93
103
|
}
|
94
104
|
}
|
95
105
|
|
96
|
-
|
97
|
-
if (this->model_.has_value()) {
|
98
|
-
BLECharacteristic *model =
|
99
|
-
this->device_information_service_->create_characteristic(MODEL_UUID, BLECharacteristic::PROPERTY_READ);
|
100
|
-
model->set_value(this->model_.value());
|
101
|
-
} else {
|
102
|
-
BLECharacteristic *model =
|
103
|
-
this->device_information_service_->create_characteristic(MODEL_UUID, BLECharacteristic::PROPERTY_READ);
|
104
|
-
model->set_value(ESPHOME_BOARD);
|
105
|
-
}
|
106
|
-
|
107
|
-
BLECharacteristic *version =
|
108
|
-
this->device_information_service_->create_characteristic(VERSION_UUID, BLECharacteristic::PROPERTY_READ);
|
109
|
-
version->set_value("ESPHome " ESPHOME_VERSION);
|
110
|
-
|
111
|
-
BLECharacteristic *manufacturer =
|
112
|
-
this->device_information_service_->create_characteristic(MANUFACTURER_UUID, BLECharacteristic::PROPERTY_READ);
|
113
|
-
manufacturer->set_value(this->manufacturer_);
|
114
|
-
|
115
|
-
return true;
|
116
|
-
}
|
117
|
-
|
118
|
-
void BLEServer::create_service(ESPBTUUID uuid, bool advertise, uint16_t num_handles, uint8_t inst_id) {
|
106
|
+
BLEService *BLEServer::create_service(ESPBTUUID uuid, bool advertise, uint16_t num_handles) {
|
119
107
|
ESP_LOGV(TAG, "Creating BLE service - %s", uuid.to_string().c_str());
|
120
|
-
//
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
108
|
+
// Calculate the inst_id for the service
|
109
|
+
uint8_t inst_id = 0;
|
110
|
+
for (; inst_id < 0xFF; inst_id++) {
|
111
|
+
if (this->get_service(uuid, inst_id) == nullptr) {
|
112
|
+
break;
|
113
|
+
}
|
114
|
+
}
|
115
|
+
if (inst_id == 0xFF) {
|
116
|
+
ESP_LOGW(TAG, "Could not create BLE service %s, too many instances", uuid.to_string().c_str());
|
117
|
+
return nullptr;
|
125
118
|
}
|
126
|
-
service =
|
127
|
-
|
128
|
-
|
119
|
+
BLEService *service = // NOLINT(cppcoreguidelines-owning-memory)
|
120
|
+
new BLEService(uuid, num_handles, inst_id, advertise);
|
121
|
+
this->services_.emplace(BLEServer::get_service_key(uuid, inst_id), service);
|
122
|
+
if (this->parent_->is_active() && this->registered_) {
|
123
|
+
service->do_create(this);
|
124
|
+
}
|
125
|
+
return service;
|
129
126
|
}
|
130
127
|
|
131
|
-
void BLEServer::remove_service(ESPBTUUID uuid) {
|
132
|
-
ESP_LOGV(TAG, "Removing BLE service - %s", uuid.to_string().c_str());
|
133
|
-
BLEService *service = this->get_service(uuid);
|
128
|
+
void BLEServer::remove_service(ESPBTUUID uuid, uint8_t inst_id) {
|
129
|
+
ESP_LOGV(TAG, "Removing BLE service - %s %d", uuid.to_string().c_str(), inst_id);
|
130
|
+
BLEService *service = this->get_service(uuid, inst_id);
|
134
131
|
if (service == nullptr) {
|
135
|
-
ESP_LOGW(TAG, "BLE service %s not
|
132
|
+
ESP_LOGW(TAG, "BLE service %s %d does not exist", uuid.to_string().c_str(), inst_id);
|
136
133
|
return;
|
137
134
|
}
|
138
135
|
service->do_delete();
|
139
136
|
delete service; // NOLINT(cppcoreguidelines-owning-memory)
|
140
|
-
this->services_.erase(uuid
|
137
|
+
this->services_.erase(BLEServer::get_service_key(uuid, inst_id));
|
141
138
|
}
|
142
139
|
|
143
|
-
BLEService *BLEServer::get_service(ESPBTUUID uuid) {
|
140
|
+
BLEService *BLEServer::get_service(ESPBTUUID uuid, uint8_t inst_id) {
|
144
141
|
BLEService *service = nullptr;
|
145
|
-
if (this->services_.count(uuid
|
146
|
-
service = this->services_.at(uuid
|
142
|
+
if (this->services_.count(BLEServer::get_service_key(uuid, inst_id)) > 0) {
|
143
|
+
service = this->services_.at(BLEServer::get_service_key(uuid, inst_id));
|
147
144
|
}
|
148
145
|
return service;
|
149
146
|
}
|
150
147
|
|
148
|
+
std::string BLEServer::get_service_key(ESPBTUUID uuid, uint8_t inst_id) {
|
149
|
+
return uuid.to_string() + std::to_string(inst_id);
|
150
|
+
}
|
151
|
+
|
151
152
|
void BLEServer::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
|
152
153
|
esp_ble_gatts_cb_param_t *param) {
|
153
154
|
switch (event) {
|
154
155
|
case ESP_GATTS_CONNECT_EVT: {
|
155
156
|
ESP_LOGD(TAG, "BLE Client connected");
|
156
|
-
this->add_client_(param->connect.conn_id
|
157
|
-
this->
|
158
|
-
for (auto *component : this->service_components_) {
|
159
|
-
component->on_client_connect();
|
160
|
-
}
|
157
|
+
this->add_client_(param->connect.conn_id);
|
158
|
+
this->emit_(BLEServerEvt::EmptyEvt::ON_CONNECT, param->connect.conn_id);
|
161
159
|
break;
|
162
160
|
}
|
163
161
|
case ESP_GATTS_DISCONNECT_EVT: {
|
164
162
|
ESP_LOGD(TAG, "BLE Client disconnected");
|
165
|
-
|
166
|
-
this->connected_clients_--;
|
163
|
+
this->remove_client_(param->disconnect.conn_id);
|
167
164
|
this->parent_->advertising_start();
|
168
|
-
|
169
|
-
component->on_client_disconnect();
|
170
|
-
}
|
165
|
+
this->emit_(BLEServerEvt::EmptyEvt::ON_DISCONNECT, param->disconnect.conn_id);
|
171
166
|
break;
|
172
167
|
}
|
173
168
|
case ESP_GATTS_REG_EVT: {
|
@@ -4,36 +4,38 @@
|
|
4
4
|
#include "ble_characteristic.h"
|
5
5
|
|
6
6
|
#include "esphome/components/esp32_ble/ble.h"
|
7
|
-
#include "esphome/components/esp32_ble/ble_advertising.h"
|
8
7
|
#include "esphome/components/esp32_ble/ble_uuid.h"
|
9
|
-
#include "esphome/components/
|
8
|
+
#include "esphome/components/bytebuffer/bytebuffer.h"
|
10
9
|
#include "esphome/core/component.h"
|
11
10
|
#include "esphome/core/helpers.h"
|
12
|
-
#include "esphome/core/preferences.h"
|
13
11
|
|
14
12
|
#include <memory>
|
15
13
|
#include <vector>
|
16
14
|
#include <unordered_map>
|
15
|
+
#include <unordered_set>
|
17
16
|
|
18
17
|
#ifdef USE_ESP32
|
19
18
|
|
20
|
-
#include <esp_gap_ble_api.h>
|
21
19
|
#include <esp_gatts_api.h>
|
22
20
|
|
23
21
|
namespace esphome {
|
24
22
|
namespace esp32_ble_server {
|
25
23
|
|
26
24
|
using namespace esp32_ble;
|
25
|
+
using namespace bytebuffer;
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
virtual void start();
|
33
|
-
virtual void stop();
|
27
|
+
namespace BLEServerEvt {
|
28
|
+
enum EmptyEvt {
|
29
|
+
ON_CONNECT,
|
30
|
+
ON_DISCONNECT,
|
34
31
|
};
|
32
|
+
} // namespace BLEServerEvt
|
35
33
|
|
36
|
-
class BLEServer : public Component,
|
34
|
+
class BLEServer : public Component,
|
35
|
+
public GATTsEventHandler,
|
36
|
+
public BLEStatusEventHandler,
|
37
|
+
public Parented<ESP32BLE>,
|
38
|
+
public EventEmitter<BLEServerEvt::EmptyEvt, uint16_t> {
|
37
39
|
public:
|
38
40
|
void setup() override;
|
39
41
|
void loop() override;
|
@@ -44,47 +46,41 @@ class BLEServer : public Component, public GATTsEventHandler, public BLEStatusEv
|
|
44
46
|
void teardown();
|
45
47
|
bool is_running();
|
46
48
|
|
47
|
-
void set_manufacturer(const std::string &manufacturer) { this->manufacturer_ = manufacturer; }
|
48
|
-
void set_model(const std::string &model) { this->model_ = model; }
|
49
49
|
void set_manufacturer_data(const std::vector<uint8_t> &data) {
|
50
50
|
this->manufacturer_data_ = data;
|
51
51
|
this->restart_advertising_();
|
52
52
|
}
|
53
53
|
|
54
|
-
|
55
|
-
void remove_service(ESPBTUUID uuid);
|
56
|
-
BLEService *get_service(ESPBTUUID uuid);
|
54
|
+
BLEService *create_service(ESPBTUUID uuid, bool advertise = false, uint16_t num_handles = 15);
|
55
|
+
void remove_service(ESPBTUUID uuid, uint8_t inst_id = 0);
|
56
|
+
BLEService *get_service(ESPBTUUID uuid, uint8_t inst_id = 0);
|
57
|
+
void enqueue_start_service(BLEService *service) { this->services_to_start_.push_back(service); }
|
58
|
+
void set_device_information_service(BLEService *service) { this->device_information_service_ = service; }
|
57
59
|
|
58
60
|
esp_gatt_if_t get_gatts_if() { return this->gatts_if_; }
|
59
|
-
uint32_t get_connected_client_count() { return this->
|
60
|
-
const std::
|
61
|
+
uint32_t get_connected_client_count() { return this->clients_.size(); }
|
62
|
+
const std::unordered_set<uint16_t> &get_clients() { return this->clients_; }
|
61
63
|
|
62
64
|
void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
|
63
65
|
esp_ble_gatts_cb_param_t *param) override;
|
64
66
|
|
65
67
|
void ble_before_disabled_event_handler() override;
|
66
68
|
|
67
|
-
void register_service_component(BLEServiceComponent *component) { this->service_components_.push_back(component); }
|
68
|
-
|
69
69
|
protected:
|
70
|
-
|
70
|
+
static std::string get_service_key(ESPBTUUID uuid, uint8_t inst_id);
|
71
71
|
void restart_advertising_();
|
72
72
|
|
73
|
-
void add_client_(uint16_t conn_id
|
74
|
-
|
73
|
+
void add_client_(uint16_t conn_id) { this->clients_.insert(conn_id); }
|
74
|
+
void remove_client_(uint16_t conn_id) { this->clients_.erase(conn_id); }
|
75
75
|
|
76
|
-
std::
|
77
|
-
optional<std::string> model_;
|
78
|
-
std::vector<uint8_t> manufacturer_data_;
|
76
|
+
std::vector<uint8_t> manufacturer_data_{};
|
79
77
|
esp_gatt_if_t gatts_if_{0};
|
80
78
|
bool registered_{false};
|
81
79
|
|
82
|
-
|
83
|
-
std::unordered_map<
|
84
|
-
std::
|
85
|
-
BLEService *device_information_service_;
|
86
|
-
|
87
|
-
std::vector<BLEServiceComponent *> service_components_;
|
80
|
+
std::unordered_set<uint16_t> clients_;
|
81
|
+
std::unordered_map<std::string, BLEService *> services_{};
|
82
|
+
std::vector<BLEService *> services_to_start_{};
|
83
|
+
BLEService *device_information_service_{};
|
88
84
|
|
89
85
|
enum State : uint8_t {
|
90
86
|
INIT = 0x00,
|