esphome 2025.9.2__py3-none-any.whl → 2025.10.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 +87 -31
- esphome/address_cache.py +142 -0
- esphome/automation.py +130 -32
- esphome/build_gen/platformio.py +1 -3
- esphome/codegen.py +1 -0
- esphome/components/animation/animation.cpp +2 -2
- esphome/components/api/__init__.py +167 -3
- esphome/components/api/api_connection.cpp +84 -41
- esphome/components/api/api_connection.h +22 -16
- esphome/components/api/api_frame_helper.cpp +33 -19
- esphome/components/api/api_frame_helper.h +19 -4
- esphome/components/api/api_frame_helper_noise.cpp +41 -53
- esphome/components/api/api_frame_helper_noise.h +1 -1
- esphome/components/api/api_frame_helper_plaintext.cpp +22 -31
- esphome/components/api/api_frame_helper_plaintext.h +1 -1
- esphome/components/api/api_pb2.cpp +189 -15
- esphome/components/api/api_pb2.h +132 -20
- esphome/components/api/api_pb2_dump.cpp +97 -9
- esphome/components/api/api_pb2_service.cpp +118 -160
- esphome/components/api/api_pb2_service.h +31 -3
- esphome/components/api/api_server.cpp +78 -11
- esphome/components/api/api_server.h +32 -4
- esphome/components/api/custom_api_device.h +8 -8
- esphome/components/api/homeassistant_service.h +123 -6
- esphome/components/api/proto.h +6 -2
- esphome/components/api/user_services.h +2 -2
- esphome/components/as7341/sensor.py +1 -1
- esphome/components/audio/__init__.py +1 -1
- esphome/components/audio/audio.cpp +1 -1
- esphome/components/audio/audio_decoder.cpp +9 -9
- esphome/components/bl0906/bl0906.cpp +2 -2
- esphome/components/bl0942/bl0942.cpp +2 -2
- esphome/components/ble_client/__init__.py +1 -1
- esphome/components/bluetooth_proxy/__init__.py +4 -30
- esphome/components/bluetooth_proxy/bluetooth_connection.cpp +11 -4
- esphome/components/bluetooth_proxy/bluetooth_connection.h +2 -2
- esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +2 -2
- esphome/components/camera_encoder/__init__.py +2 -4
- esphome/components/camera_encoder/esp32_camera_jpeg_encoder.cpp +4 -2
- esphome/components/camera_encoder/esp32_camera_jpeg_encoder.h +3 -1
- esphome/components/canbus/canbus.cpp +7 -5
- esphome/components/canbus/canbus.h +4 -4
- esphome/components/captive_portal/__init__.py +18 -1
- esphome/components/captive_portal/captive_portal.cpp +40 -46
- esphome/components/captive_portal/captive_portal.h +20 -22
- esphome/components/captive_portal/dns_server_esp32_idf.cpp +205 -0
- esphome/components/captive_portal/dns_server_esp32_idf.h +27 -0
- esphome/components/ccs811/ccs811.cpp +1 -1
- esphome/components/climate/climate.cpp +10 -7
- esphome/components/cm1106/cm1106.cpp +1 -1
- esphome/components/copy/lock/copy_lock.cpp +1 -1
- esphome/components/cover/cover.cpp +1 -0
- esphome/components/daikin_arc/daikin_arc.cpp +19 -12
- esphome/components/deep_sleep/__init__.py +9 -2
- esphome/components/deep_sleep/deep_sleep_component.h +11 -9
- esphome/components/deep_sleep/deep_sleep_esp32.cpp +51 -27
- esphome/components/ektf2232/touchscreen/__init__.py +8 -5
- esphome/components/ektf2232/touchscreen/ektf2232.cpp +4 -4
- esphome/components/ektf2232/touchscreen/ektf2232.h +2 -2
- esphome/components/epaper_spi/__init__.py +1 -0
- esphome/components/epaper_spi/display.py +80 -0
- esphome/components/epaper_spi/epaper_spi.cpp +227 -0
- esphome/components/epaper_spi/epaper_spi.h +93 -0
- esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.cpp +42 -0
- esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.h +45 -0
- esphome/components/epaper_spi/epaper_spi_spectra_e6.cpp +135 -0
- esphome/components/epaper_spi/epaper_spi_spectra_e6.h +23 -0
- esphome/components/es7210/es7210.cpp +3 -3
- esphome/components/esp32/__init__.py +254 -339
- esphome/components/esp32/boards.py +81 -0
- esphome/components/esp32/preferences.cpp +23 -17
- esphome/components/esp32_ble/__init__.py +159 -44
- esphome/components/esp32_ble/ble.cpp +47 -3
- esphome/components/esp32_ble/ble.h +18 -0
- esphome/components/esp32_ble/ble_advertising.cpp +7 -3
- esphome/components/esp32_ble/ble_advertising.h +4 -0
- esphome/components/esp32_ble/ble_uuid.cpp +16 -42
- esphome/components/esp32_ble_beacon/__init__.py +3 -4
- esphome/components/esp32_ble_client/ble_client_base.cpp +14 -12
- esphome/components/esp32_ble_server/__init__.py +28 -14
- esphome/components/esp32_ble_server/ble_characteristic.cpp +67 -57
- esphome/components/esp32_ble_server/ble_characteristic.h +27 -16
- esphome/components/esp32_ble_server/ble_descriptor.cpp +4 -3
- esphome/components/esp32_ble_server/ble_descriptor.h +13 -9
- esphome/components/esp32_ble_server/ble_server.cpp +59 -24
- esphome/components/esp32_ble_server/ble_server.h +38 -20
- esphome/components/esp32_ble_server/ble_server_automations.cpp +49 -33
- esphome/components/esp32_ble_server/ble_server_automations.h +39 -24
- esphome/components/esp32_ble_tracker/__init__.py +25 -80
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +2 -4
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +0 -3
- esphome/components/esp32_camera/__init__.py +1 -3
- esphome/components/esp32_can/esp32_can.cpp +22 -4
- esphome/components/esp32_can/esp32_can.h +3 -0
- esphome/components/esp32_hosted/__init__.py +2 -1
- esphome/components/esp32_improv/esp32_improv_component.cpp +102 -44
- esphome/components/esp32_improv/esp32_improv_component.h +6 -1
- esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
- esphome/components/esp8266/__init__.py +3 -3
- esphome/components/esphome/ota/__init__.py +21 -2
- esphome/components/esphome/ota/ota_esphome.cpp +455 -145
- esphome/components/esphome/ota/ota_esphome.h +49 -2
- esphome/components/ethernet/__init__.py +39 -22
- esphome/components/ethernet/ethernet_component.cpp +28 -5
- esphome/components/ethernet/ethernet_component.h +5 -1
- esphome/components/external_components/__init__.py +8 -6
- esphome/components/fingerprint_grow/fingerprint_grow.cpp +1 -1
- esphome/components/fingerprint_grow/fingerprint_grow.h +2 -1
- esphome/components/font/__init__.py +5 -5
- esphome/components/graph/graph.cpp +1 -1
- esphome/components/graphical_display_menu/graphical_display_menu.cpp +3 -2
- esphome/components/haier/hon_climate.cpp +2 -2
- esphome/components/haier/hon_climate.h +1 -1
- esphome/components/hdc1080/hdc1080.cpp +42 -34
- esphome/components/hdc1080/hdc1080.h +1 -3
- esphome/components/homeassistant/number/homeassistant_number.cpp +2 -2
- esphome/components/homeassistant/switch/homeassistant_switch.cpp +2 -2
- esphome/components/http_request/__init__.py +3 -3
- esphome/components/htu21d/htu21d.cpp +13 -18
- esphome/components/htu21d/htu21d.h +1 -1
- esphome/components/i2s_audio/__init__.py +1 -2
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +1 -1
- esphome/components/ili9xxx/ili9xxx_display.cpp +2 -2
- esphome/components/improv_serial/improv_serial_component.cpp +12 -15
- esphome/components/improv_serial/improv_serial_component.h +6 -8
- esphome/components/json/json_util.cpp +35 -43
- esphome/components/json/json_util.h +57 -0
- esphome/components/kamstrup_kmp/kamstrup_kmp.cpp +2 -2
- esphome/components/key_collector/key_collector.h +4 -4
- esphome/components/libretiny/__init__.py +6 -6
- esphome/components/libretiny/preferences.cpp +23 -16
- esphome/components/light/light_call.cpp +98 -120
- esphome/components/light/light_call.h +17 -7
- esphome/components/lm75b/__init__.py +0 -0
- esphome/components/lm75b/lm75b.cpp +39 -0
- esphome/components/lm75b/lm75b.h +19 -0
- esphome/components/lm75b/sensor.py +34 -0
- esphome/components/lock/lock.h +12 -6
- esphome/components/logger/__init__.py +15 -27
- esphome/components/logger/logger.cpp +10 -20
- esphome/components/logger/logger.h +105 -62
- esphome/components/logger/logger_esp32.cpp +0 -48
- esphome/components/logger/logger_zephyr.cpp +2 -3
- esphome/components/logger/select/logger_level_select.cpp +6 -7
- esphome/components/logger/select/logger_level_select.h +7 -0
- esphome/components/ltr501/ltr501.cpp +7 -6
- esphome/components/ltr_als_ps/ltr_als_ps.cpp +7 -6
- esphome/components/matrix_keypad/matrix_keypad.h +4 -4
- esphome/components/max7219digit/max7219digit.cpp +1 -1
- esphome/components/mcp2515/mcp2515.cpp +31 -3
- esphome/components/mcp2515/mcp2515_defs.h +3 -1
- esphome/components/md5/md5.cpp +0 -26
- esphome/components/md5/md5.h +10 -20
- esphome/components/mdns/__init__.py +19 -6
- esphome/components/mdns/mdns_component.cpp +27 -59
- esphome/components/mdns/mdns_component.h +23 -10
- esphome/components/mdns/mdns_esp32.cpp +7 -7
- esphome/components/mdns/mdns_esp8266.cpp +6 -6
- esphome/components/mdns/mdns_libretiny.cpp +3 -3
- esphome/components/mdns/mdns_rp2040.cpp +3 -3
- esphome/components/mipi/__init__.py +1 -5
- esphome/components/mipi_spi/display.py +24 -8
- esphome/components/mipi_spi/mipi_spi.h +3 -3
- esphome/components/mixer/speaker/mixer_speaker.cpp +3 -3
- esphome/components/mmc5603/mmc5603.cpp +3 -3
- esphome/components/modbus/modbus.cpp +27 -13
- esphome/components/modbus/modbus.h +5 -3
- esphome/components/modbus/modbus_definitions.h +86 -0
- esphome/components/modbus_controller/__init__.py +29 -1
- esphome/components/modbus_controller/const.py +4 -0
- esphome/components/modbus_controller/modbus_controller.cpp +38 -13
- esphome/components/modbus_controller/modbus_controller.h +18 -29
- esphome/components/mpr121/mpr121.cpp +41 -42
- esphome/components/mpr121/mpr121.h +0 -1
- esphome/components/nau7802/nau7802.cpp +2 -2
- esphome/components/network/__init__.py +7 -3
- esphome/components/nextion/display.py +4 -4
- esphome/components/nextion/nextion.cpp +8 -8
- esphome/components/number/__init__.py +2 -0
- esphome/components/number/number_call.cpp +23 -12
- esphome/components/number/number_call.h +5 -0
- esphome/components/online_image/bmp_image.cpp +2 -1
- esphome/components/online_image/jpeg_image.cpp +4 -2
- esphome/components/openthread/openthread.cpp +6 -7
- esphome/components/openthread/openthread.h +0 -1
- esphome/components/ota/ota_backend.h +1 -0
- esphome/components/packages/__init__.py +10 -8
- esphome/components/packet_transport/packet_transport.cpp +2 -0
- esphome/components/pid/pid_controller.cpp +1 -1
- esphome/components/prometheus/prometheus_handler.cpp +239 -239
- esphome/components/psram/__init__.py +30 -28
- esphome/components/qmc5883l/qmc5883l.cpp +15 -0
- esphome/components/qmc5883l/qmc5883l.h +3 -0
- esphome/components/qmc5883l/sensor.py +31 -12
- esphome/components/remote_base/gobox_protocol.cpp +3 -3
- esphome/components/remote_receiver/__init__.py +14 -2
- esphome/components/remote_receiver/{remote_receiver_esp8266.cpp → remote_receiver.cpp} +2 -2
- esphome/components/remote_receiver/remote_receiver.h +4 -0
- esphome/components/remote_receiver/remote_receiver_esp32.cpp +18 -1
- esphome/components/remote_transmitter/__init__.py +2 -2
- esphome/components/remote_transmitter/remote_transmitter.cpp +103 -0
- esphome/components/rp2040/__init__.py +11 -11
- esphome/components/rtttl/rtttl.cpp +2 -2
- esphome/components/scd30/sensor.py +1 -1
- esphome/components/script/__init__.py +1 -1
- esphome/components/script/script.h +7 -7
- esphome/components/select/select.cpp +5 -4
- esphome/components/select/select_call.cpp +1 -1
- esphome/components/sensirion_common/i2c_sensirion.cpp +2 -1
- esphome/components/sensor/__init__.py +2 -0
- esphome/components/sha256/__init__.py +22 -0
- esphome/components/sha256/sha256.cpp +116 -0
- esphome/components/sha256/sha256.h +60 -0
- esphome/components/sim800l/sim800l.cpp +8 -4
- esphome/components/socket/lwip_raw_tcp_impl.cpp +34 -6
- esphome/components/sonoff_d1/sonoff_d1.cpp +1 -1
- esphome/components/spi/__init__.py +0 -3
- esphome/components/split_buffer/__init__.py +5 -0
- esphome/components/split_buffer/split_buffer.cpp +133 -0
- esphome/components/split_buffer/split_buffer.h +40 -0
- esphome/components/sps30/sps30.cpp +14 -10
- esphome/components/sps30/sps30.h +2 -0
- esphome/components/st7567_i2c/st7567_i2c.cpp +3 -1
- esphome/components/st7789v/st7789v.cpp +3 -2
- esphome/components/statsd/statsd.cpp +1 -1
- esphome/components/substitutions/__init__.py +3 -1
- esphome/components/substitutions/jinja.py +13 -3
- esphome/components/sx126x/__init__.py +16 -0
- esphome/components/sx126x/sx126x.cpp +15 -1
- esphome/components/sx126x/sx126x.h +9 -1
- esphome/components/sx126x/sx126x_reg.h +2 -0
- esphome/components/text_sensor/text_sensor.cpp +16 -0
- esphome/components/text_sensor/text_sensor.h +3 -10
- esphome/components/tormatic/tormatic_cover.cpp +1 -1
- esphome/components/tuya/select/tuya_select.cpp +1 -1
- esphome/components/tuya/tuya.cpp +29 -4
- esphome/components/uart/__init__.py +36 -26
- esphome/components/uart/uart.h +6 -0
- esphome/components/uart/uart_component.cpp +8 -0
- esphome/components/uart/uart_component.h +28 -0
- esphome/components/uart/uart_component_esp_idf.cpp +64 -10
- esphome/components/uart/uart_component_esp_idf.h +5 -2
- esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +1 -1
- esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.cpp +1 -1
- esphome/components/uponor_smatrix/uponor_smatrix.cpp +3 -3
- esphome/components/usb_host/__init__.py +2 -1
- esphome/components/usb_host/usb_host.h +82 -13
- esphome/components/usb_host/usb_host_client.cpp +180 -24
- esphome/components/usb_host/usb_host_component.cpp +1 -1
- esphome/components/usb_uart/__init__.py +0 -1
- esphome/components/usb_uart/ch34x.cpp +4 -4
- esphome/components/usb_uart/cp210x.cpp +3 -3
- esphome/components/usb_uart/usb_uart.cpp +88 -32
- esphome/components/usb_uart/usb_uart.h +30 -6
- esphome/components/valve/valve.cpp +1 -0
- esphome/components/veml7700/veml7700.cpp +7 -6
- esphome/components/version/version_text_sensor.cpp +2 -1
- esphome/components/voice_assistant/voice_assistant.cpp +3 -3
- esphome/components/waveshare_epaper/waveshare_epaper.cpp +4 -4
- esphome/components/web_server/list_entities.cpp +3 -4
- esphome/components/web_server/list_entities.h +8 -10
- esphome/components/web_server/ota/__init__.py +1 -1
- esphome/components/web_server/ota/ota_web_server.cpp +9 -3
- esphome/components/web_server/web_server.cpp +509 -404
- esphome/components/web_server/web_server.h +5 -6
- esphome/components/web_server/web_server_v1.cpp +21 -19
- esphome/components/web_server_base/__init__.py +5 -2
- esphome/components/web_server_base/web_server_base.h +27 -7
- esphome/components/web_server_idf/__init__.py +1 -1
- esphome/components/web_server_idf/multipart.cpp +2 -2
- esphome/components/web_server_idf/multipart.h +2 -2
- esphome/components/web_server_idf/utils.cpp +2 -2
- esphome/components/web_server_idf/utils.h +2 -2
- esphome/components/web_server_idf/web_server_idf.cpp +118 -26
- esphome/components/web_server_idf/web_server_idf.h +12 -10
- esphome/components/wifi/__init__.py +13 -11
- esphome/components/wifi/wifi_component.cpp +73 -56
- esphome/components/wifi/wifi_component.h +4 -4
- esphome/components/wifi/wifi_component_esp8266.cpp +1 -1
- esphome/components/wifi/wifi_component_esp_idf.cpp +24 -4
- esphome/components/wireguard/__init__.py +1 -1
- esphome/components/wts01/__init__.py +0 -0
- esphome/components/wts01/sensor.py +41 -0
- esphome/components/wts01/wts01.cpp +91 -0
- esphome/components/wts01/wts01.h +27 -0
- esphome/components/zephyr/__init__.py +5 -5
- esphome/components/zwave_proxy/__init__.py +43 -0
- esphome/components/zwave_proxy/zwave_proxy.cpp +346 -0
- esphome/components/zwave_proxy/zwave_proxy.h +93 -0
- esphome/config.py +79 -24
- esphome/config_validation.py +13 -15
- esphome/const.py +9 -2
- esphome/core/__init__.py +31 -22
- esphome/core/component.cpp +28 -18
- esphome/core/component_iterator.h +2 -1
- esphome/core/config.py +15 -15
- esphome/core/defines.h +19 -0
- esphome/core/hash_base.h +56 -0
- esphome/core/helpers.cpp +19 -3
- esphome/core/helpers.h +26 -0
- esphome/core/scheduler.cpp +5 -21
- esphome/core/scheduler.h +19 -8
- esphome/core/string_ref.h +1 -1
- esphome/core/time.cpp +5 -5
- esphome/cpp_generator.py +4 -29
- esphome/dashboard/const.py +21 -4
- esphome/dashboard/core.py +10 -8
- esphome/dashboard/dns.py +15 -0
- esphome/dashboard/entries.py +15 -21
- esphome/dashboard/models.py +76 -0
- esphome/dashboard/settings.py +7 -7
- esphome/dashboard/status/mdns.py +46 -2
- esphome/dashboard/web_server.py +367 -93
- esphome/espota2.py +111 -31
- esphome/external_files.py +6 -7
- esphome/git.py +8 -0
- esphome/helpers.py +124 -77
- esphome/loader.py +8 -9
- esphome/platformio_api.py +25 -18
- esphome/storage_json.py +26 -21
- esphome/types.py +30 -2
- esphome/util.py +32 -16
- esphome/vscode.py +8 -8
- esphome/wizard.py +10 -10
- esphome/writer.py +50 -15
- esphome/yaml_util.py +37 -31
- esphome/zeroconf.py +12 -3
- {esphome-2025.9.2.dist-info → esphome-2025.10.0b1.dist-info}/METADATA +11 -11
- {esphome-2025.9.2.dist-info → esphome-2025.10.0b1.dist-info}/RECORD +333 -313
- esphome/components/event_emitter/__init__.py +0 -5
- esphome/components/event_emitter/event_emitter.cpp +0 -14
- esphome/components/event_emitter/event_emitter.h +0 -63
- esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -125
- esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +0 -107
- esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +0 -110
- esphome/components/uart/uart_component_esp32_arduino.cpp +0 -214
- esphome/components/uart/uart_component_esp32_arduino.h +0 -60
- esphome/components/wifi/wifi_component_esp32_arduino.cpp +0 -860
- esphome/core/string_ref.cpp +0 -12
- esphome/dashboard/util/file.py +0 -63
- {esphome-2025.9.2.dist-info → esphome-2025.10.0b1.dist-info}/WHEEL +0 -0
- {esphome-2025.9.2.dist-info → esphome-2025.10.0b1.dist-info}/entry_points.txt +0 -0
- {esphome-2025.9.2.dist-info → esphome-2025.10.0b1.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.9.2.dist-info → esphome-2025.10.0b1.dist-info}/top_level.txt +0 -0
@@ -2,11 +2,12 @@
|
|
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
5
|
#include "esphome/components/bytebuffer/bytebuffer.h"
|
7
6
|
|
8
7
|
#include <vector>
|
9
|
-
#include <
|
8
|
+
#include <span>
|
9
|
+
#include <functional>
|
10
|
+
#include <memory>
|
10
11
|
|
11
12
|
#ifdef USE_ESP32
|
12
13
|
|
@@ -23,22 +24,10 @@ namespace esp32_ble_server {
|
|
23
24
|
|
24
25
|
using namespace esp32_ble;
|
25
26
|
using namespace bytebuffer;
|
26
|
-
using namespace event_emitter;
|
27
27
|
|
28
28
|
class BLEService;
|
29
29
|
|
30
|
-
|
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> {
|
30
|
+
class BLECharacteristic {
|
42
31
|
public:
|
43
32
|
BLECharacteristic(ESPBTUUID uuid, uint32_t properties);
|
44
33
|
~BLECharacteristic();
|
@@ -77,6 +66,15 @@ class BLECharacteristic : public EventEmitter<BLECharacteristicEvt::VectorEvt, s
|
|
77
66
|
bool is_created();
|
78
67
|
bool is_failed();
|
79
68
|
|
69
|
+
// Direct callback registration - only allocates when callback is set
|
70
|
+
void on_write(std::function<void(std::span<const uint8_t>, uint16_t)> &&callback) {
|
71
|
+
this->on_write_callback_ =
|
72
|
+
std::make_unique<std::function<void(std::span<const uint8_t>, uint16_t)>>(std::move(callback));
|
73
|
+
}
|
74
|
+
void on_read(std::function<void(uint16_t)> &&callback) {
|
75
|
+
this->on_read_callback_ = std::make_unique<std::function<void(uint16_t)>>(std::move(callback));
|
76
|
+
}
|
77
|
+
|
80
78
|
protected:
|
81
79
|
bool write_event_{false};
|
82
80
|
BLEService *service_{};
|
@@ -89,7 +87,20 @@ class BLECharacteristic : public EventEmitter<BLECharacteristicEvt::VectorEvt, s
|
|
89
87
|
SemaphoreHandle_t set_value_lock_;
|
90
88
|
|
91
89
|
std::vector<BLEDescriptor *> descriptors_;
|
92
|
-
|
90
|
+
|
91
|
+
struct ClientNotificationEntry {
|
92
|
+
uint16_t conn_id;
|
93
|
+
bool indicate; // true = indicate, false = notify
|
94
|
+
};
|
95
|
+
std::vector<ClientNotificationEntry> clients_to_notify_;
|
96
|
+
|
97
|
+
void remove_client_from_notify_list_(uint16_t conn_id);
|
98
|
+
ClientNotificationEntry *find_client_in_notify_list_(uint16_t conn_id);
|
99
|
+
|
100
|
+
void set_property_bit_(esp_gatt_char_prop_t bit, bool value);
|
101
|
+
|
102
|
+
std::unique_ptr<std::function<void(std::span<const uint8_t>, uint16_t)>> on_write_callback_;
|
103
|
+
std::unique_ptr<std::function<void(uint16_t)>> on_read_callback_;
|
93
104
|
|
94
105
|
esp_gatt_perm_t permissions_ = ESP_GATT_PERM_READ | ESP_GATT_PERM_WRITE;
|
95
106
|
|
@@ -74,9 +74,10 @@ void BLEDescriptor::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_
|
|
74
74
|
break;
|
75
75
|
this->value_.attr_len = param->write.len;
|
76
76
|
memcpy(this->value_.attr_value, param->write.value, param->write.len);
|
77
|
-
this->
|
78
|
-
|
79
|
-
|
77
|
+
if (this->on_write_callback_) {
|
78
|
+
(*this->on_write_callback_)(std::span<const uint8_t>(param->write.value, param->write.len),
|
79
|
+
param->write.conn_id);
|
80
|
+
}
|
80
81
|
break;
|
81
82
|
}
|
82
83
|
default:
|
@@ -1,30 +1,26 @@
|
|
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
4
|
#include "esphome/components/bytebuffer/bytebuffer.h"
|
6
5
|
|
7
6
|
#ifdef USE_ESP32
|
8
7
|
|
9
8
|
#include <esp_gatt_defs.h>
|
10
9
|
#include <esp_gatts_api.h>
|
10
|
+
#include <span>
|
11
|
+
#include <functional>
|
12
|
+
#include <memory>
|
11
13
|
|
12
14
|
namespace esphome {
|
13
15
|
namespace esp32_ble_server {
|
14
16
|
|
15
17
|
using namespace esp32_ble;
|
16
18
|
using namespace bytebuffer;
|
17
|
-
using namespace event_emitter;
|
18
19
|
|
19
20
|
class BLECharacteristic;
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
ON_WRITE,
|
24
|
-
};
|
25
|
-
} // namespace BLEDescriptorEvt
|
26
|
-
|
27
|
-
class BLEDescriptor : public EventEmitter<BLEDescriptorEvt::VectorEvt, std::vector<uint8_t>, uint16_t> {
|
22
|
+
// Base class for BLE descriptors
|
23
|
+
class BLEDescriptor {
|
28
24
|
public:
|
29
25
|
BLEDescriptor(ESPBTUUID uuid, uint16_t max_len = 100, bool read = true, bool write = true);
|
30
26
|
virtual ~BLEDescriptor();
|
@@ -39,6 +35,12 @@ class BLEDescriptor : public EventEmitter<BLEDescriptorEvt::VectorEvt, std::vect
|
|
39
35
|
bool is_created() { return this->state_ == CREATED; }
|
40
36
|
bool is_failed() { return this->state_ == FAILED; }
|
41
37
|
|
38
|
+
// Direct callback registration - only allocates when callback is set
|
39
|
+
void on_write(std::function<void(std::span<const uint8_t>, uint16_t)> &&callback) {
|
40
|
+
this->on_write_callback_ =
|
41
|
+
std::make_unique<std::function<void(std::span<const uint8_t>, uint16_t)>>(std::move(callback));
|
42
|
+
}
|
43
|
+
|
42
44
|
protected:
|
43
45
|
BLECharacteristic *characteristic_{nullptr};
|
44
46
|
ESPBTUUID uuid_;
|
@@ -46,6 +48,8 @@ class BLEDescriptor : public EventEmitter<BLEDescriptorEvt::VectorEvt, std::vect
|
|
46
48
|
|
47
49
|
esp_attr_value_t value_{};
|
48
50
|
|
51
|
+
std::unique_ptr<std::function<void(std::span<const uint8_t>, uint16_t)>> on_write_callback_;
|
52
|
+
|
49
53
|
esp_gatt_perm_t permissions_{};
|
50
54
|
|
51
55
|
enum State : uint8_t {
|
@@ -70,11 +70,11 @@ void BLEServer::loop() {
|
|
70
70
|
// it is at the top of the GATT table
|
71
71
|
this->device_information_service_->do_create(this);
|
72
72
|
// Create all services previously created
|
73
|
-
for (auto &
|
74
|
-
if (
|
73
|
+
for (auto &entry : this->services_) {
|
74
|
+
if (entry.service == this->device_information_service_) {
|
75
75
|
continue;
|
76
76
|
}
|
77
|
-
|
77
|
+
entry.service->do_create(this);
|
78
78
|
}
|
79
79
|
this->state_ = STARTING_SERVICE;
|
80
80
|
}
|
@@ -118,7 +118,7 @@ BLEService *BLEServer::create_service(ESPBTUUID uuid, bool advertise, uint16_t n
|
|
118
118
|
}
|
119
119
|
BLEService *service = // NOLINT(cppcoreguidelines-owning-memory)
|
120
120
|
new BLEService(uuid, num_handles, inst_id, advertise);
|
121
|
-
this->services_.
|
121
|
+
this->services_.push_back({uuid, inst_id, service});
|
122
122
|
if (this->parent_->is_active() && this->registered_) {
|
123
123
|
service->do_create(this);
|
124
124
|
}
|
@@ -127,26 +127,32 @@ BLEService *BLEServer::create_service(ESPBTUUID uuid, bool advertise, uint16_t n
|
|
127
127
|
|
128
128
|
void BLEServer::remove_service(ESPBTUUID uuid, uint8_t inst_id) {
|
129
129
|
ESP_LOGV(TAG, "Removing BLE service - %s %d", uuid.to_string().c_str(), inst_id);
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
130
|
+
for (auto it = this->services_.begin(); it != this->services_.end(); ++it) {
|
131
|
+
if (it->uuid == uuid && it->inst_id == inst_id) {
|
132
|
+
it->service->do_delete();
|
133
|
+
delete it->service; // NOLINT(cppcoreguidelines-owning-memory)
|
134
|
+
this->services_.erase(it);
|
135
|
+
return;
|
136
|
+
}
|
134
137
|
}
|
135
|
-
service
|
136
|
-
delete service; // NOLINT(cppcoreguidelines-owning-memory)
|
137
|
-
this->services_.erase(BLEServer::get_service_key(uuid, inst_id));
|
138
|
+
ESP_LOGW(TAG, "BLE service %s %d does not exist", uuid.to_string().c_str(), inst_id);
|
138
139
|
}
|
139
140
|
|
140
141
|
BLEService *BLEServer::get_service(ESPBTUUID uuid, uint8_t inst_id) {
|
141
|
-
|
142
|
-
|
143
|
-
|
142
|
+
for (auto &entry : this->services_) {
|
143
|
+
if (entry.uuid == uuid && entry.inst_id == inst_id) {
|
144
|
+
return entry.service;
|
145
|
+
}
|
144
146
|
}
|
145
|
-
return
|
147
|
+
return nullptr;
|
146
148
|
}
|
147
149
|
|
148
|
-
|
149
|
-
|
150
|
+
void BLEServer::dispatch_callbacks_(CallbackType type, uint16_t conn_id) {
|
151
|
+
for (auto &entry : this->callbacks_) {
|
152
|
+
if (entry.type == type) {
|
153
|
+
entry.callback(conn_id);
|
154
|
+
}
|
155
|
+
}
|
150
156
|
}
|
151
157
|
|
152
158
|
void BLEServer::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
|
@@ -155,14 +161,14 @@ void BLEServer::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t ga
|
|
155
161
|
case ESP_GATTS_CONNECT_EVT: {
|
156
162
|
ESP_LOGD(TAG, "BLE Client connected");
|
157
163
|
this->add_client_(param->connect.conn_id);
|
158
|
-
this->
|
164
|
+
this->dispatch_callbacks_(CallbackType::ON_CONNECT, param->connect.conn_id);
|
159
165
|
break;
|
160
166
|
}
|
161
167
|
case ESP_GATTS_DISCONNECT_EVT: {
|
162
168
|
ESP_LOGD(TAG, "BLE Client disconnected");
|
163
169
|
this->remove_client_(param->disconnect.conn_id);
|
164
170
|
this->parent_->advertising_start();
|
165
|
-
this->
|
171
|
+
this->dispatch_callbacks_(CallbackType::ON_DISCONNECT, param->disconnect.conn_id);
|
166
172
|
break;
|
167
173
|
}
|
168
174
|
case ESP_GATTS_REG_EVT: {
|
@@ -174,17 +180,46 @@ void BLEServer::gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t ga
|
|
174
180
|
break;
|
175
181
|
}
|
176
182
|
|
177
|
-
for (
|
178
|
-
|
183
|
+
for (auto &entry : this->services_) {
|
184
|
+
entry.service->gatts_event_handler(event, gatts_if, param);
|
185
|
+
}
|
186
|
+
}
|
187
|
+
|
188
|
+
int8_t BLEServer::find_client_index_(uint16_t conn_id) const {
|
189
|
+
for (uint8_t i = 0; i < this->client_count_; i++) {
|
190
|
+
if (this->clients_[i] == conn_id)
|
191
|
+
return i;
|
192
|
+
}
|
193
|
+
return -1;
|
194
|
+
}
|
195
|
+
|
196
|
+
void BLEServer::add_client_(uint16_t conn_id) {
|
197
|
+
// Check if already in list
|
198
|
+
if (this->find_client_index_(conn_id) >= 0)
|
199
|
+
return;
|
200
|
+
// Add if there's space
|
201
|
+
if (this->client_count_ < USE_ESP32_BLE_MAX_CONNECTIONS) {
|
202
|
+
this->clients_[this->client_count_++] = conn_id;
|
203
|
+
} else {
|
204
|
+
// This should never happen since max clients is known at compile time
|
205
|
+
ESP_LOGE(TAG, "Client array full");
|
206
|
+
}
|
207
|
+
}
|
208
|
+
|
209
|
+
void BLEServer::remove_client_(uint16_t conn_id) {
|
210
|
+
int8_t index = this->find_client_index_(conn_id);
|
211
|
+
if (index >= 0) {
|
212
|
+
// Replace with last element and decrement count (client order not preserved)
|
213
|
+
this->clients_[index] = this->clients_[--this->client_count_];
|
179
214
|
}
|
180
215
|
}
|
181
216
|
|
182
217
|
void BLEServer::ble_before_disabled_event_handler() {
|
183
218
|
// Delete all clients
|
184
|
-
this->
|
219
|
+
this->client_count_ = 0;
|
185
220
|
// Delete all services
|
186
|
-
for (auto &
|
187
|
-
|
221
|
+
for (auto &entry : this->services_) {
|
222
|
+
entry.service->do_delete();
|
188
223
|
}
|
189
224
|
this->registered_ = false;
|
190
225
|
this->state_ = INIT;
|
@@ -12,7 +12,7 @@
|
|
12
12
|
#include <memory>
|
13
13
|
#include <vector>
|
14
14
|
#include <unordered_map>
|
15
|
-
#include <
|
15
|
+
#include <functional>
|
16
16
|
|
17
17
|
#ifdef USE_ESP32
|
18
18
|
|
@@ -24,18 +24,7 @@ namespace esp32_ble_server {
|
|
24
24
|
using namespace esp32_ble;
|
25
25
|
using namespace bytebuffer;
|
26
26
|
|
27
|
-
|
28
|
-
enum EmptyEvt {
|
29
|
-
ON_CONNECT,
|
30
|
-
ON_DISCONNECT,
|
31
|
-
};
|
32
|
-
} // namespace BLEServerEvt
|
33
|
-
|
34
|
-
class BLEServer : public Component,
|
35
|
-
public GATTsEventHandler,
|
36
|
-
public BLEStatusEventHandler,
|
37
|
-
public Parented<ESP32BLE>,
|
38
|
-
public EventEmitter<BLEServerEvt::EmptyEvt, uint16_t> {
|
27
|
+
class BLEServer : public Component, public GATTsEventHandler, public BLEStatusEventHandler, public Parented<ESP32BLE> {
|
39
28
|
public:
|
40
29
|
void setup() override;
|
41
30
|
void loop() override;
|
@@ -57,27 +46,56 @@ class BLEServer : public Component,
|
|
57
46
|
void set_device_information_service(BLEService *service) { this->device_information_service_ = service; }
|
58
47
|
|
59
48
|
esp_gatt_if_t get_gatts_if() { return this->gatts_if_; }
|
60
|
-
uint32_t get_connected_client_count() { return this->
|
61
|
-
const
|
49
|
+
uint32_t get_connected_client_count() { return this->client_count_; }
|
50
|
+
const uint16_t *get_clients() const { return this->clients_; }
|
51
|
+
uint8_t get_client_count() const { return this->client_count_; }
|
62
52
|
|
63
53
|
void gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if,
|
64
54
|
esp_ble_gatts_cb_param_t *param) override;
|
65
55
|
|
66
56
|
void ble_before_disabled_event_handler() override;
|
67
57
|
|
58
|
+
// Direct callback registration - supports multiple callbacks
|
59
|
+
void on_connect(std::function<void(uint16_t)> &&callback) {
|
60
|
+
this->callbacks_.push_back({CallbackType::ON_CONNECT, std::move(callback)});
|
61
|
+
}
|
62
|
+
void on_disconnect(std::function<void(uint16_t)> &&callback) {
|
63
|
+
this->callbacks_.push_back({CallbackType::ON_DISCONNECT, std::move(callback)});
|
64
|
+
}
|
65
|
+
|
68
66
|
protected:
|
69
|
-
|
67
|
+
enum class CallbackType : uint8_t {
|
68
|
+
ON_CONNECT,
|
69
|
+
ON_DISCONNECT,
|
70
|
+
};
|
71
|
+
|
72
|
+
struct CallbackEntry {
|
73
|
+
CallbackType type;
|
74
|
+
std::function<void(uint16_t)> callback;
|
75
|
+
};
|
76
|
+
|
77
|
+
struct ServiceEntry {
|
78
|
+
ESPBTUUID uuid;
|
79
|
+
uint8_t inst_id;
|
80
|
+
BLEService *service;
|
81
|
+
};
|
82
|
+
|
70
83
|
void restart_advertising_();
|
71
84
|
|
72
|
-
|
73
|
-
void
|
85
|
+
int8_t find_client_index_(uint16_t conn_id) const;
|
86
|
+
void add_client_(uint16_t conn_id);
|
87
|
+
void remove_client_(uint16_t conn_id);
|
88
|
+
void dispatch_callbacks_(CallbackType type, uint16_t conn_id);
|
89
|
+
|
90
|
+
std::vector<CallbackEntry> callbacks_;
|
74
91
|
|
75
92
|
std::vector<uint8_t> manufacturer_data_{};
|
76
93
|
esp_gatt_if_t gatts_if_{0};
|
77
94
|
bool registered_{false};
|
78
95
|
|
79
|
-
|
80
|
-
|
96
|
+
uint16_t clients_[USE_ESP32_BLE_MAX_CONNECTIONS]{};
|
97
|
+
uint8_t client_count_{0};
|
98
|
+
std::vector<ServiceEntry> services_{};
|
81
99
|
std::vector<BLEService *> services_to_start_{};
|
82
100
|
BLEService *device_information_service_{};
|
83
101
|
|
@@ -9,66 +9,82 @@ namespace esp32_ble_server_automations {
|
|
9
9
|
|
10
10
|
using namespace esp32_ble;
|
11
11
|
|
12
|
+
#ifdef USE_ESP32_BLE_SERVER_CHARACTERISTIC_ON_WRITE
|
12
13
|
Trigger<std::vector<uint8_t>, uint16_t> *BLETriggers::create_characteristic_on_write_trigger(
|
13
14
|
BLECharacteristic *characteristic) {
|
14
15
|
Trigger<std::vector<uint8_t>, uint16_t> *on_write_trigger = // NOLINT(cppcoreguidelines-owning-memory)
|
15
16
|
new Trigger<std::vector<uint8_t>, uint16_t>();
|
16
|
-
characteristic->
|
17
|
-
|
18
|
-
|
17
|
+
characteristic->on_write([on_write_trigger](std::span<const uint8_t> data, uint16_t id) {
|
18
|
+
// Convert span to vector for trigger
|
19
|
+
on_write_trigger->trigger(std::vector<uint8_t>(data.begin(), data.end()), id);
|
20
|
+
});
|
19
21
|
return on_write_trigger;
|
20
22
|
}
|
23
|
+
#endif
|
21
24
|
|
25
|
+
#ifdef USE_ESP32_BLE_SERVER_DESCRIPTOR_ON_WRITE
|
22
26
|
Trigger<std::vector<uint8_t>, uint16_t> *BLETriggers::create_descriptor_on_write_trigger(BLEDescriptor *descriptor) {
|
23
27
|
Trigger<std::vector<uint8_t>, uint16_t> *on_write_trigger = // NOLINT(cppcoreguidelines-owning-memory)
|
24
28
|
new Trigger<std::vector<uint8_t>, uint16_t>();
|
25
|
-
descriptor->
|
26
|
-
|
27
|
-
|
29
|
+
descriptor->on_write([on_write_trigger](std::span<const uint8_t> data, uint16_t id) {
|
30
|
+
// Convert span to vector for trigger
|
31
|
+
on_write_trigger->trigger(std::vector<uint8_t>(data.begin(), data.end()), id);
|
32
|
+
});
|
28
33
|
return on_write_trigger;
|
29
34
|
}
|
35
|
+
#endif
|
30
36
|
|
37
|
+
#ifdef USE_ESP32_BLE_SERVER_ON_CONNECT
|
31
38
|
Trigger<uint16_t> *BLETriggers::create_server_on_connect_trigger(BLEServer *server) {
|
32
39
|
Trigger<uint16_t> *on_connect_trigger = new Trigger<uint16_t>(); // NOLINT(cppcoreguidelines-owning-memory)
|
33
|
-
server->
|
34
|
-
[on_connect_trigger](uint16_t conn_id) { on_connect_trigger->trigger(conn_id); });
|
40
|
+
server->on_connect([on_connect_trigger](uint16_t conn_id) { on_connect_trigger->trigger(conn_id); });
|
35
41
|
return on_connect_trigger;
|
36
42
|
}
|
43
|
+
#endif
|
37
44
|
|
45
|
+
#ifdef USE_ESP32_BLE_SERVER_ON_DISCONNECT
|
38
46
|
Trigger<uint16_t> *BLETriggers::create_server_on_disconnect_trigger(BLEServer *server) {
|
39
47
|
Trigger<uint16_t> *on_disconnect_trigger = new Trigger<uint16_t>(); // NOLINT(cppcoreguidelines-owning-memory)
|
40
|
-
server->
|
41
|
-
[on_disconnect_trigger](uint16_t conn_id) { on_disconnect_trigger->trigger(conn_id); });
|
48
|
+
server->on_disconnect([on_disconnect_trigger](uint16_t conn_id) { on_disconnect_trigger->trigger(conn_id); });
|
42
49
|
return on_disconnect_trigger;
|
43
50
|
}
|
51
|
+
#endif
|
44
52
|
|
53
|
+
#ifdef USE_ESP32_BLE_SERVER_SET_VALUE_ACTION
|
45
54
|
void BLECharacteristicSetValueActionManager::set_listener(BLECharacteristic *characteristic,
|
46
|
-
EventEmitterListenerID listener_id,
|
47
55
|
const std::function<void()> &pre_notify_listener) {
|
48
|
-
//
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
56
|
+
// Find and remove existing listener for this characteristic
|
57
|
+
auto *existing = this->find_listener_(characteristic);
|
58
|
+
if (existing != nullptr) {
|
59
|
+
// Remove from vector
|
60
|
+
this->remove_listener_(characteristic);
|
61
|
+
}
|
62
|
+
// Save the entry to the vector
|
63
|
+
this->listeners_.push_back({characteristic, pre_notify_listener});
|
64
|
+
}
|
65
|
+
|
66
|
+
BLECharacteristicSetValueActionManager::ListenerEntry *BLECharacteristicSetValueActionManager::find_listener_(
|
67
|
+
BLECharacteristic *characteristic) {
|
68
|
+
for (auto &entry : this->listeners_) {
|
69
|
+
if (entry.characteristic == characteristic) {
|
70
|
+
return &entry;
|
71
|
+
}
|
72
|
+
}
|
73
|
+
return nullptr;
|
74
|
+
}
|
75
|
+
|
76
|
+
void BLECharacteristicSetValueActionManager::remove_listener_(BLECharacteristic *characteristic) {
|
77
|
+
// Since we typically have very few listeners, optimize by swapping with back and popping
|
78
|
+
for (size_t i = 0; i < this->listeners_.size(); i++) {
|
79
|
+
if (this->listeners_[i].characteristic == characteristic) {
|
80
|
+
// Swap with last element and pop (safe even when i is the last element)
|
81
|
+
this->listeners_[i] = this->listeners_.back();
|
82
|
+
this->listeners_.pop_back();
|
83
|
+
return;
|
84
|
+
}
|
59
85
|
}
|
60
|
-
// Create a new listener for the pre-notify event
|
61
|
-
EventEmitterListenerID pre_notify_listener_id =
|
62
|
-
this->on(BLECharacteristicSetValueActionEvt::PRE_NOTIFY,
|
63
|
-
[pre_notify_listener, characteristic](const BLECharacteristic *evt_characteristic) {
|
64
|
-
// Only call the pre-notify listener if the characteristic is the one we are interested in
|
65
|
-
if (characteristic == evt_characteristic) {
|
66
|
-
pre_notify_listener();
|
67
|
-
}
|
68
|
-
});
|
69
|
-
// Save the pair listener_id, pre_notify_listener_id to the map
|
70
|
-
this->listeners_[characteristic] = std::make_pair(listener_id, pre_notify_listener_id);
|
71
86
|
}
|
87
|
+
#endif
|
72
88
|
|
73
89
|
} // namespace esp32_ble_server_automations
|
74
90
|
} // namespace esp32_ble_server
|
@@ -4,11 +4,9 @@
|
|
4
4
|
#include "ble_characteristic.h"
|
5
5
|
#include "ble_descriptor.h"
|
6
6
|
|
7
|
-
#include "esphome/components/event_emitter/event_emitter.h"
|
8
7
|
#include "esphome/core/automation.h"
|
9
8
|
|
10
9
|
#include <vector>
|
11
|
-
#include <unordered_map>
|
12
10
|
#include <functional>
|
13
11
|
|
14
12
|
#ifdef USE_ESP32
|
@@ -19,41 +17,53 @@ namespace esp32_ble_server {
|
|
19
17
|
namespace esp32_ble_server_automations {
|
20
18
|
|
21
19
|
using namespace esp32_ble;
|
22
|
-
using namespace event_emitter;
|
23
20
|
|
24
21
|
class BLETriggers {
|
25
22
|
public:
|
23
|
+
#ifdef USE_ESP32_BLE_SERVER_CHARACTERISTIC_ON_WRITE
|
26
24
|
static Trigger<std::vector<uint8_t>, uint16_t> *create_characteristic_on_write_trigger(
|
27
25
|
BLECharacteristic *characteristic);
|
26
|
+
#endif
|
27
|
+
#ifdef USE_ESP32_BLE_SERVER_DESCRIPTOR_ON_WRITE
|
28
28
|
static Trigger<std::vector<uint8_t>, uint16_t> *create_descriptor_on_write_trigger(BLEDescriptor *descriptor);
|
29
|
+
#endif
|
30
|
+
#ifdef USE_ESP32_BLE_SERVER_ON_CONNECT
|
29
31
|
static Trigger<uint16_t> *create_server_on_connect_trigger(BLEServer *server);
|
32
|
+
#endif
|
33
|
+
#ifdef USE_ESP32_BLE_SERVER_ON_DISCONNECT
|
30
34
|
static Trigger<uint16_t> *create_server_on_disconnect_trigger(BLEServer *server);
|
35
|
+
#endif
|
31
36
|
};
|
32
37
|
|
33
|
-
|
34
|
-
PRE_NOTIFY,
|
35
|
-
};
|
36
|
-
|
38
|
+
#ifdef USE_ESP32_BLE_SERVER_SET_VALUE_ACTION
|
37
39
|
// Class to make sure only one BLECharacteristicSetValueAction is active at a time for each characteristic
|
38
|
-
class BLECharacteristicSetValueActionManager
|
39
|
-
: public EventEmitter<BLECharacteristicSetValueActionEvt, BLECharacteristic *> {
|
40
|
+
class BLECharacteristicSetValueActionManager {
|
40
41
|
public:
|
41
42
|
// Singleton pattern
|
42
43
|
static BLECharacteristicSetValueActionManager *get_instance() {
|
43
44
|
static BLECharacteristicSetValueActionManager instance;
|
44
45
|
return &instance;
|
45
46
|
}
|
46
|
-
void set_listener(BLECharacteristic *characteristic,
|
47
|
-
|
48
|
-
EventEmitterListenerID get_listener(BLECharacteristic *characteristic) {
|
49
|
-
return this->listeners_[characteristic].first;
|
50
|
-
}
|
47
|
+
void set_listener(BLECharacteristic *characteristic, const std::function<void()> &pre_notify_listener);
|
48
|
+
bool has_listener(BLECharacteristic *characteristic) { return this->find_listener_(characteristic) != nullptr; }
|
51
49
|
void emit_pre_notify(BLECharacteristic *characteristic) {
|
52
|
-
this->
|
50
|
+
for (const auto &entry : this->listeners_) {
|
51
|
+
if (entry.characteristic == characteristic) {
|
52
|
+
entry.pre_notify_listener();
|
53
|
+
break;
|
54
|
+
}
|
55
|
+
}
|
53
56
|
}
|
54
57
|
|
55
58
|
private:
|
56
|
-
|
59
|
+
struct ListenerEntry {
|
60
|
+
BLECharacteristic *characteristic;
|
61
|
+
std::function<void()> pre_notify_listener;
|
62
|
+
};
|
63
|
+
std::vector<ListenerEntry> listeners_;
|
64
|
+
|
65
|
+
ListenerEntry *find_listener_(BLECharacteristic *characteristic);
|
66
|
+
void remove_listener_(BLECharacteristic *characteristic);
|
57
67
|
};
|
58
68
|
|
59
69
|
template<typename... Ts> class BLECharacteristicSetValueAction : public Action<Ts...> {
|
@@ -63,32 +73,34 @@ template<typename... Ts> class BLECharacteristicSetValueAction : public Action<T
|
|
63
73
|
void set_buffer(ByteBuffer buffer) { this->set_buffer(buffer.get_data()); }
|
64
74
|
void play(Ts... x) override {
|
65
75
|
// If the listener is already set, do nothing
|
66
|
-
if (BLECharacteristicSetValueActionManager::get_instance()->
|
76
|
+
if (BLECharacteristicSetValueActionManager::get_instance()->has_listener(this->parent_))
|
67
77
|
return;
|
68
78
|
// Set initial value
|
69
79
|
this->parent_->set_value(this->buffer_.value(x...));
|
70
80
|
// Set the listener for read events
|
71
|
-
this->
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
});
|
81
|
+
this->parent_->on_read([this, x...](uint16_t id) {
|
82
|
+
// Set the value of the characteristic every time it is read
|
83
|
+
this->parent_->set_value(this->buffer_.value(x...));
|
84
|
+
});
|
76
85
|
// Set the listener in the global manager so only one BLECharacteristicSetValueAction is set for each characteristic
|
77
86
|
BLECharacteristicSetValueActionManager::get_instance()->set_listener(
|
78
|
-
this->parent_,
|
87
|
+
this->parent_, [this, x...]() { this->parent_->set_value(this->buffer_.value(x...)); });
|
79
88
|
}
|
80
89
|
|
81
90
|
protected:
|
82
91
|
BLECharacteristic *parent_;
|
83
|
-
EventEmitterListenerID listener_id_;
|
84
92
|
};
|
93
|
+
#endif // USE_ESP32_BLE_SERVER_SET_VALUE_ACTION
|
85
94
|
|
95
|
+
#ifdef USE_ESP32_BLE_SERVER_NOTIFY_ACTION
|
86
96
|
template<typename... Ts> class BLECharacteristicNotifyAction : public Action<Ts...> {
|
87
97
|
public:
|
88
98
|
BLECharacteristicNotifyAction(BLECharacteristic *characteristic) : parent_(characteristic) {}
|
89
99
|
void play(Ts... x) override {
|
100
|
+
#ifdef USE_ESP32_BLE_SERVER_SET_VALUE_ACTION
|
90
101
|
// Call the pre-notify event
|
91
102
|
BLECharacteristicSetValueActionManager::get_instance()->emit_pre_notify(this->parent_);
|
103
|
+
#endif
|
92
104
|
// Notify the characteristic
|
93
105
|
this->parent_->notify();
|
94
106
|
}
|
@@ -96,7 +108,9 @@ template<typename... Ts> class BLECharacteristicNotifyAction : public Action<Ts.
|
|
96
108
|
protected:
|
97
109
|
BLECharacteristic *parent_;
|
98
110
|
};
|
111
|
+
#endif // USE_ESP32_BLE_SERVER_NOTIFY_ACTION
|
99
112
|
|
113
|
+
#ifdef USE_ESP32_BLE_SERVER_DESCRIPTOR_SET_VALUE_ACTION
|
100
114
|
template<typename... Ts> class BLEDescriptorSetValueAction : public Action<Ts...> {
|
101
115
|
public:
|
102
116
|
BLEDescriptorSetValueAction(BLEDescriptor *descriptor) : parent_(descriptor) {}
|
@@ -107,6 +121,7 @@ template<typename... Ts> class BLEDescriptorSetValueAction : public Action<Ts...
|
|
107
121
|
protected:
|
108
122
|
BLEDescriptor *parent_;
|
109
123
|
};
|
124
|
+
#endif // USE_ESP32_BLE_SERVER_DESCRIPTOR_SET_VALUE_ACTION
|
110
125
|
|
111
126
|
} // namespace esp32_ble_server_automations
|
112
127
|
} // namespace esp32_ble_server
|